Confused with -Include параметр командлета Get-ChildItem
Из документации:
-Include
Извлекает только указанные элементы. Значение этого параметра соответствует параметр Path. Введите путь элемент или шаблон, например "*.txt". Подстановочные знаки разрешены.
Параметр Include эффективен только тогда, когда команда включает параметр Recurse или путь приводит к содержанию каталог, такой как C:\Windows *, где подстановочный знак указывает содержимое каталога C:\Windows.
Мое первое понимание:
c:\test\a.txt
c:\test\b.txt
Итак, чтобы получить "a.txt" и "b.txt", я могу написать:
gci -Path "c:\test\*" -Include "*.txt"
И это работает. Но теперь рассмотрим такую иерархию:
c:\test\a.txt
c:\test\b.txt
c:\test\c.txt\c.txt
Эта же команда возвращает: a.txt, b.txt, c.txt
Фактическая логика выглядит следующим образом:
-Include используется для соответствия всем объектам, указанным -Path. Если согласованный элемент это файл - вернуть его. Если сопоставлено элемент - это папка, загляните внутрь и возвращать соответствующие дети первого уровня.
Кроме того, в документации говорится:
Параметр Include эффективен только тогда, когда команда включает параметр Recurse или путь приводит к содержанию каталог...
Это неправильно. Например.
gci -Path "c:\test" -Include "*.txt"
Он ничего не возвращает, а без -Include я получаю содержимое папки. Итак -Include определенно "эффективен". Что на самом деле происходит здесь? Параметр -Path указывает "c:\test", а -Include пытается сопоставить этот путь. Поскольку "*.txt" не соответствует "test", поэтому ничего не возвращается. Но посмотрите на это:
gci -Path "c:\test" -Include "*t"
Он возвращает a.txt, b.txt и c.txt как "* t", соответствующий "test" и сопоставляет все дочерние элементы.
В конце концов, даже зная, как Include работает сейчас, я не понимаю, когда его использовать. Зачем мне это нужно, чтобы посмотреть в подпапки? Почему это должно быть так сложно?
Ответы
Ответ 1
Вы запутываете использование -include. Флаг -include применяется к пути, а не содержимому пути. Без использования рекурсивного флага единственный путь, о котором идет речь, - это указанный вами путь. Вот почему в последнем примере, который вы дали, путь c:\test
имеет t в пути и, следовательно, соответствует "*t"
.
Вы можете проверить это, попробовав следующие
gci -path "c:\test" -in *e*
Это все равно приведет к появлению всех дочерних элементов в каталоге, но не соответствует ни одному из них.
Причиной того, что -include является более эффективным с параметром recurse, является то, что вы в конечном итоге применяете шаблон для каждого пути в иерархии.
Ответ 2
Попробуйте параметр -filter (он поддерживает только одно расширение):
dir -filter *.txt
Ответ 3
Отвечая на ответ JaredPar, чтобы выполнить сопоставление образцов с Get-ChildItem, вы можете использовать общие групповые символы оболочки.
Например:
get-childitem "c:\test\t?st.txt"
где "?" является подстановочным знаком, соответствующим любому символу или
get-childitem "c:\test\*.txt"
который будет соответствовать любому имени файла, заканчивающегося на ".txt".
Это должно помочь вам найти более простое поведение.
Ответ 4
Я просто задал аналогичный вопрос и получил три быстрых ответа относительно Get-Help для Get-ChildItem.
Ответ в полном описании команды (Get-Help Get-ChildItem -full):
The Include parameter is effective only when the command includes the
Параметр Recurse или путь ведет к содержимое каталога, например, C:\Windows *, где шаблон character указывает содержимое каталог C:\Windows.
Таким образом, следующее будет работать без рекурсию.
PS C:\foo > Get-childitem -path "c:\foo *" -Include *.txt
Из вопроса о переполнении стека PowerShell Scripting - Get-ChildItem.
Надеюсь, это поможет: -)
Ответ 5
Включение \*
в конце пути должно обойти проблему
PS C:\logfiles> Get-ChildItem .\* -include *.log
Это должно возвращать файлы .log из текущего рабочего каталога (C:\logfiles
)
Пример Alex показывает, что также будет возвращен каталог с именем foo.log. Когда я попробовал это, это было не то, но через 6 лет, и это может быть из обновлений PS.
Однако вы можете использовать дочерний элемент Mode
для исключения каталогов, которые, как я думаю.
PS C:\logfiles> Get-Childitem .\* -include *.log | where-object {$_.mode -notmatch "d"}
Это должно исключать что-либо с установленным режимом "каталог".
Ответ 6
get-childitem -include работает только с -recursive или подстановочным знаком в пути. Я считаю это ошибкой [Хотя в PS 6 все было по-другому].