Передача параметра фильтра Powershell Get-ChildItem через строковую переменную не работает - PullRequest
1 голос
/ 16 июня 2019

В моем скрипте ниже приведена функция, которая возвращает строку как "* .csproj", "* .vbproj", "* .sln". Предполагая, что я всегда передаю строку типа «csproj, vbproj, sln» в параметр $ filter:

Function Create-Filter($filter)
{    
    $str = $filter.Split(',') | ForEach-Object {"""*.$($_.Trim())"""}

    $str = $str -join ', '
    [string]$str
    return
}

Позже в моем сценарии я выполняю:

$filter = Create-Filter($filter)
$myFiles = Get-ChildItem $source -Include $filter -Recurse  

Но $ myFiles пуст, Get-ChildItem ничего не возвращает. Я знаю, что проблема заключается в параметре $ filter при передаче в Get-ChildItem, но я не знаю, как решить эту проблему.

В любом случае, с консоли powershell, если я сделаю это ниже, то это работает:

PS > $filter = "*.csproj", "*.vbproj", "*.sln"
PS > Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $filter -Recurse

Так что я делаю не так?

Моя версия PowerShell, как показано на рисунке ниже:

enter image description here

ОБНОВЛЕНИЕ (РЕШЕНИЕ) : Решение, предложенное AdminOfThings, работает. В моем случае применение AdminOfThings не работало, потому что я допустил ошибку в своем коде. Я присваивал значение, возвращаемое функцией Create-Filter, той же переменной, что и передаваемый в качестве аргумента, как показано ниже:

$filter = Create-Filter ($filter)
Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $filter -Recurse

Для того, чтобы заставить это работать, я сделал ниже:

$formattedfilter = Create-Filter ($filter)
Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $formattedfilter -Recurse

... то есть, используя другую переменную для присвоения возвращаемого значения по функции, вместо того, чтобы использовать то же, что я передавал в качестве аргумента.

Ответы [ 2 ]

2 голосов
/ 16 июня 2019

Короче говоря, вам нужно удалить буквенные кавычки (заменить тройные двойные кавычки одинарными двойными кавычками), -Join и приведение строки ([string]) из вашей функции. По сути, все, что структурирует ваш вывод, нужно удалить.

Function Create-Filter($filter)
{    
    $filter.Split(',') | ForEach-Object {"*.$($_.Trim())"}
    return
}

Параметр -Include принимает одну строку или массив строк. Когда вы передаете -Include "string1","string2", вы передаете массив строк в команду. В вашем фильтре вы создаете одну строку, которая включает буквальные кавычки и запятые. Тонкость здесь заключается в том, что запятые в кавычках создают строку, содержащую кавычки, тогда как кавычки BETWEEN запятые создают разделенный запятыми список строк. Так эффективно, команда читает -Include '"string1","string2"', которая ничего не найдет. Даже если ваша функция выводит текст, который выглядит идентично тому, что вы вводите непосредственно в команду, PowerShell интерпретирует эти значения по-разному.

Вы можете увидеть поведение ниже, когда вывод вашей функции интерпретируется PowerShell как одна строка.

create-filter ("txt","csv")
"*.txt", "*.csv"
(create-filter ("txt","csv")).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Синтаксис массива (список типов строк, разделенных запятыми), приведенный ниже, выдает другой результат.

"*.txt","*.csv"
*.txt
*.csv
("*.txt","*.csv").gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

Выполнение кода:

$str = "txt,csv"
create-filter $str
*.txt
*.csv
$filter = create-filter $str
Get-ChildItem . -Include $filter -Recurse
    Directory: C:\temp\test1


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         6/8/2019  10:47 AM             68 -44.csv
-a----         6/8/2019  10:47 AM            101 -54.csv
-a----        6/11/2019   8:50 AM            229 count.txt
-a----        6/11/2019   8:58 AM            170 destination.txt
-a----        6/11/2019   8:53 AM            302 f.txt
-a----        6/12/2019   6:36 AM            294 hashash.txt
-a----         6/6/2019   1:14 PM              4 jaf.csv
-a----         6/6/2019   1:31 PM              0 job1.txt
0 голосов
/ 16 июня 2019

Хм, я бы использовал -фильтр, который быстрее.

ls -r D:\Path\To\My\Root\Folder -filter *.csproj,*.vbproj,*.sln

РЕДАКТИРОВАТЬ: Ой, это не работает. Но это так. Я не уверен, для чего вам нужна эта функция.

ls -r D:\Path\To\My\Root\Folder -include *.csproj,*.vbproj,*.sln

или

$source = 'D:\Path\To\My\Root\Folder'
$filter = '*.csproj','*.vbproj.*','*.sln' # or
$filter = echo *.csproj,*.vbproj,*.sln 

ls -r $source -include $filter
...