Powershell Get-ChildItem -Filter работает по-разному с предложением Where с одинаковым значением
У меня есть папка на сервере MyFolder. Существуют дополнительные папки под названием MyFolder.1, MyFolder.2, MyFolder.3 и т.д.
Если я запустил:
gci C:\Sample | ? { $_.Name -like "MyFolder.*" }
Я получаю ожидаемый результат:
Directory: C:\Sample
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 16/10/2012 12:16 MyFolder.1
d---- 16/10/2012 12:16 MyFolder.2
d---- 16/10/2012 12:16 MyFolder.3
Однако, если я запустил:
gci C:\Sample -Filter "MyFolder.*"
Я получаю:
Directory: C:\Sample
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 16/10/2012 12:16 MyFolder
d---- 16/10/2012 12:16 MyFolder.1
d---- 16/10/2012 12:16 MyFolder.2
d---- 16/10/2012 12:16 MyFolder.3
Я смущен тем, как MyFolder включен в вывод. Я ожидаю, что результат будет таким же.
В интерактивной справке показано, что синтаксис фильтра основан на провайдере, но я не уверен, что поставщик используется в этом случае.
Не хватает ли здесь фундаментального знания? Я попытался передать строку регулярных выражений в фильтр, например "MyFolder\.*"
, но это просто ничего не возвращает. Я уверен, что мне не хватает чего-то простого.
Я запускаю версию Powershell версии 2.
Разрешение
Спасибо Роману Кузьмину за то, что он указал на различия в сопоставлении подстановочных знаков. Ниже приводится ожидаемый результат:
gci C:\Sample\MyFolder.*
Я буду использовать этот синтаксис для облегчения в будущем для уменьшения шума в коде.
Ответы
Ответ 1
Filter
поставщика FileSystem скорее использует подстановочные знаки CMD, чем подстановочные знаки PowerShell. Символы CMD смешны и не интуитивны в некоторых случаях, в основном исторически. Вот интересное объяснение: http://blogs.msdn.com/b/oldnewthing/archive/2007/12/17/6785519.aspx
Еще один вопрос, который нужно иметь в виду: ls -Filter *.txt
фактически получает файлы типа *.txt*
в смысле PowerShell, то есть файлы с расширениями начиная с txt. Это может быть неожиданным и очень неприятным в некоторых сценариях:)
Ответ 2
gci C:\Sample -Filter "MyFolder.*" # here is a filesystem provider; use wildcard `*`,`?`
возвращает тот же результат, что и (в оболочке cmd.exe):
dir Myfolder.*
Если вам нужно регулярное выражение, это способ (-filter
не принимает регулярное выражение)
gci C:\Sample | ? { $_.Name -match '^MyFolder\..*' }
как здесь
gci C:\Sample | ? { $_.Name -like "MyFolder.*" }
сравнение в скриптблоке находится между типом [string]
.