Смущает параметр -Include командлета Get-ChildItem - PullRequest
11 голосов
/ 26 апреля 2009

Из документации:

-Include

Получает только указанные элементы. Значение этого параметра соответствует параметр Path. Введите путь элемент или шаблон, например "* .txt". Подстановочные знаки разрешены.

Параметр Включить действует только тогда, когда команда включает параметр 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. Если соответствует элемент это файл - верните его. Если соответствует Элемент - это папка, загляните внутрь и верните соответствие детям первого уровня.

Также в документации сказано:

Параметр Включить действует только тогда, когда команда включает параметр 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» и сопоставляет все дочерние элементы.

В конце концов, даже зная, как теперь работает Включить, я не понимаю, когда его использовать. Зачем мне это нужно искать внутри подпапок? Почему это должно быть так сложно?

Ответы [ 6 ]

14 голосов
/ 26 апреля 2009

Вы путаете использование -include. Флаг -include применяется к пути, а не к содержимому пути. Без использования рекурсивного флага единственный рассматриваемый путь - это указанный вами путь. Вот почему последний пример, который вы привели, работает, путь c:\test имеет t в пути и, следовательно, соответствует "*t".

Вы можете проверить это, попробовав следующее

gci -path "c:\test" -in *e*

Это все равно выдаст всех дочерних элементов в каталоге, но не соответствует ни одному из их имен.

Причина, по которой -include более эффективен с параметром recurse, заключается в том, что в итоге вы применяете подстановочный знак для каждого пути в иерархии.

9 голосов
/ 26 апреля 2009

Попробуйте параметр -filter (он поддерживает только одно расширение):

dir -filter * .txt

5 голосов
/ 26 апреля 2009

Привязка к Ответ JaredPar , чтобы выполнить сопоставление с шаблоном с Get-ChildItem, вы можете использовать общие символы оболочки.

Например:

get-childitem "c:\test\t?st.txt"

где "?" подстановочный знак, соответствующий любому одному символу или

get-childitem "c:\test\*.txt"

, которое будет соответствовать любому имени файла, оканчивающемуся на ".txt".

Это должно дать вам "более простое" поведение, которое вы искали.

2 голосов
/ 03 сентября 2009

Я только что задал похожий вопрос и получил три быстрых ответа относительно Get-Help для Get-ChildItem.

Ответ в полном описании команды (Get-Help Get-ChildItem -full):

The Include parameter is effective only when the command includes the

Параметр рекурсии или путь, ведущий к содержимое каталога, например C: \ Windows *, где подстановочный знак символ указывает на содержание каталог C: \ Windows.

Таким образом, следующее будет работать без рекурсия.

PS C: \ foo> Get-childitem -path "c: \ foo *" -Включить * .txt

Из вопроса переполнения стека Сценарии PowerShell - Get-ChildItem .

Надеюсь, это поможет: -)

0 голосов
/ 17 июня 2018

get-childitem -include работает только с -recursive или подстановочным знаком в пути. Я считаю это ошибкой. Это исправлено в Powershell 6.

0 голосов
/ 08 апреля 2015

Включая \* в конце пути, чтобы обойти проблему

PS C:\logfiles> Get-ChildItem .\* -include *.log

Это должно вернуть файлы .log из текущего рабочего каталога (C:\logfiles)

Приведенный выше пример Алекса указывает, что каталог с именем foo.log также будет возвращен. Когда я попробовал, это было не так, но прошло 6 лет, и это могло быть из обновлений PS.

Однако вы можете использовать дочерний элемент Mode для исключения каталогов, я думаю.

PS C:\logfiles> Get-Childitem .\* -include *.log | where-object {$_.mode -notmatch "d"}

Это должно исключать что-либо с установленным режимом 'directory'.

...