Powershell - проблема с Get-Childitem -include - PullRequest
1 голос
/ 28 марта 2020

Я пытаюсь написать сценарий PowerShell, который позволит пользователю передавать параметр с несколькими типами файлов, которые он хочет обработать (например, * .txt и * .docx). Когда я запускаю команду Get-Childitem с параметром -include и вручную печатаю типы файлов, это работает файл. Но когда я пытаюсь указать переменную для маски -include, она не работает (ничего не возвращает).

Проблема возникает только при использовании нескольких типов файлов $ incFiles = “” ” .txt ”” `,“ ” .docx” ””

Если я использую один тип файла, он работает просто отлично. $ incFiles = «* .txt»

$incFiles = ""
$incFiles = """*.txt""`, ""*.docx"""
Write-Host "Manual Method:" '"*.txt", "*.docx"'
Write-Host "Calcul Method:" $incFiles

Write-Host "`nManual method works"
Get-ChildItem -path "C:\users\paul\Downloads" -Recurse -Include "*.txt", "*.docx"

Write-Host "This does not work"
Get-ChildItem -path "C:\users\paul\Downloads" -Recurse -Include $incFiles

Write-Host "End"

Результаты

Manual Method: "*.txt", "*.docx"
Calcul Method: "*.txt", "*.docx"

Manual method works

Directory: C:\users\paul\Downloads\Test2
Mode                LastWriteTime         Length Name                                                                                                                           
----                -------------         ------ ----                                                                                                                           
-a----        3/28/2020   9:54 AM              0 File1.txt                                                                                                                      
-a----        3/28/2020   9:55 AM              0 File2.docx                                                                                                                     

This does not work

End

1 Ответ

0 голосов
/ 29 марта 2020

Тео и Маклайтон предоставили критический указатель в комментариях к вопросу:

$incFiles = """*.txt""`, ""*.docx"""

создает одиночная строка , чье дословное содержимое заканчивается как "*.txt", "*.docx".

В качестве отступа: обратный тик (`), escape-символ PowerShell , не обязательно, учитывая, что , не имеет особого значения внутри "..." ( расширяемая строка ).

В то время как выглядит как литерал массива , как если бы вы передавали его напрямую параметру, который принимает массив строковых значений (например, -Include в данном случае), то, что вы передаете, является одиночная строка , которая интерпретируется как одиночный шаблон подстановки, и поэтому не будет работать.

То, что вы пытаетесь сделать, потребует PowerShell для анализа содержимое строки , передаваемое как Исходный код PowerShell - т. е. потребуется дополнительный раунд оценки - чего он (к счастью) не делает. [1]

PowerShell, в отличие от других оболочек, способен передавать значения любого типа в качестве прямых аргументов командам либо с помощью переменной ($incFiles, в вашем случае), либо с помощью выражения / вложенной команды, используя (...); Например, Write-Host -Foreground Yellow ('-' * 10))

Следовательно, создает переменную $incFiles в виде массива из строк , а передает этот массив как это для параметра -Include:

# Create a string array of wildcard expressions.
# (an [object[]] instance whose elements are of type [string]).
# Note the use of '...' rather than "...", which clearly signals that
# the enclosed text should be taken *verbatim* (rather than being subject to
# *expansion* (string interpolation).
$incFiles = '*.txt', '*.docx'

# Pass the array as-is to -Include
Get-ChildItem -path "C:\users\paul\Downloads" -Recurse -Include $incFiles

Для полного обзора того, как PowerShell анализирует аргументы, не заключенные в кавычки, переданные командам, см. этот ответ .


[1] Напротив, POSIX-подобные оболочки, такие как bash, применяют дополнительную оценку к ссылкам на переменные без кавычек в ограниченной степени посредством так называемых расширений оболочки - см. этот ответ .

...