Итак, я чувствую, что это должно быть ошибкой в PowerShell, но я хотел посмотреть, считаете ли вы, ребята, что это не работает. Это довольно легко воспроизвести, но я понимаю, почему это может быть не особенно распространенным вариантом использования. Шаги, которые я изложил ниже, на самом деле не являются тем, что делал мой скрипт, я на самом деле вычислял размеры подпапок - я просто сжал его до простейшего возможного сценария, который показывает мою проблему.
Я пробовал это только в PowerShell 5.0.10240.16384, но, возможно, вскоре у меня будет возможность протестировать его в более ранней версии [Редактировать: я проверил это на PowerShell 2.0, и ошибка не появляется в этой версии — она работает, как и ожидалось]. Небольшое примечание: я везде использовал gci
как аббревиатуру Get-ChildItem. Если вы еще не знали, это работает и для ввода в PowerShell. Но проблема существует независимо от того, какой псевдоним вы используете.
Сначала создайте папку с именем Test [123]
где-нибудь под рукой. В этой папке создайте пару файлов. Мои называются Test1.txt
и Test2.txt
. В них ничего не должно быть.
Затем откройте сеанс PowerShell и Set-Location
в родительскую папку вашей новой папки Test [123]
.
Теперь запустите gci -Filter Test*
и вы должны увидеть что-то вроде:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/15/2015 3:22 PM Test [123]
Все хорошо, верно? Затем попробуйте gci -Filter Test* | gci
. Это делает вывод первого gci входом для следующего, т.е. показывает нам дочерние элементы каждого элемента, возвращаемого первым gci. Это дает нам следующее:
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/14/2015 10:21 PM 0 Test1.txt
-a---- 11/15/2015 3:55 PM 0 Test2.txt
Опять же, все хорошо - именно так, как ожидалось. Это все файлы из нашей папки Test [123]
.
Теперь попробуйте это: gci -Filter Test* | gci -Recurse
. Все, что мы изменили, это то, что второй вызов gci
теперь рекурсивный, поэтому он должен показывать нам все файлы, включая подпапки. У нас нет подпапок, поэтому мы ожидаем таких же результатов, верно?
Неправильно. Мы вообще не получаем никакого результата. Кажется очень странным, что все, что мы сделали, это добавили -Recurse
, и теперь мы получаем другой результат. Я думаю, что добавление -Recurse
никогда не должно уменьшать вывод меньше, а только больше.
А вот и следующая странность. Теперь попробуйте gci -Filter Test* | gci -Recurse -Name
. Это то же самое, что и раньше, за исключением того, что добавлен параметр -Name
. Это просто говорит о том, что нам нужен тот же результат, за исключением того, что нам нужны только имена файлов, а не полная информация о каждом элементе. Так что, скорее всего, мы ничего не ждем взамен. Но это не то, что мы получаем, мы получаем это:
Test1.txt
Test2.txt
Это нужно сломать, верно? Во-первых, -Recurse
никогда не должен уменьшать объем вывода, а во-вторых, запрос вывода в другом формате не должен изменять объем вывода, который мы получаем.
Это происходит только тогда, когда в имени папки есть квадратные скобки. Если вы создадите другую папку, только что названную Test
, и снова запустите все приведенные выше команды, вы всегда будете видеть файлы из папки Test
.
Мои исследования привели меня к параметру -LiteralPath
; однако, перефразируя приведенную выше команду как gci -Filter Test* | foreach { gci -Recurse -LiteralPath $_ }
, чтобы использовать этот параметр, по-прежнему не возвращаются выходные данные, и снова добавление параметра -Name
снова запускает возврат файлов.
Мне удалось найти обходной путь для этого, используя параметр -Name
, а затем объединив его с путем к папке, которую я ищу, а затем передав его в Get-Item
, но это сделало код длиннее и уродливее, чем он должен быть.
Итак, мой вопрос: я сделал ошибку или что-то не так понял? Или это ошибка, о которой я должен сообщить?
-Include *
в качестве обходного пути. - person user4003407   schedule 15.11.2015-Recurse
обрабатывает подстановочные знаки ([
и]
) в имени. Если вы экранируете их вручную, это тоже работает - person Mathias R. Jessen   schedule 15.11.2015[Regex]::Replace
вместо[System.Management.Automation.WildcardPattern]::Escape
? - person user4003407   schedule 16.11.2015WildcardPattern.Escape()
до 50 секунд назад :) - person Mathias R. Jessen   schedule 16.11.2015Get-ChildItem
— это полный беспорядок. Одна вещь в PS, которая никогда не дает последовательного вывода. - person beatcracker   schedule 16.11.2015