Подстановочный знак параметра -Filter
соответствует , а не , выполненному PowerShell , он передается поставщику файловой системы и в конечном итоге API Windows. Сопоставление, выполняемое там, обременено множеством унаследованных поведений и причуд, включая тот, который вы видели:
In Windows PowerShell , -Filter *.xls
эффективно ведет себя как -Filter *.xls*
. Следовательно, -Filter *.xls
соответствует, например, foo.xls
и foo.xlsx
; это происходит потому, что 8,3 (короткие) имена файлов также сопоставляются за кадром ; например, имя файла foo.xlsx
8.3 выглядит примерно так: FOO~1.XLS
; обратите внимание на усечение (и заглавные буквы) от .xlsx
до .XLS
.
В то время как поведение сопоставления коротких имен больше не происходит в PowerShell [Core] v6 + К счастью, сохраняются другие устаревшие особенности [1] , как и самое заметное отличие (которое не будет go прочь): только PowerShell подстановочные выражения (см. about_Wildcards
) поддержка диапазонов / наборов символов с помощью [...]
(например, [a-z]
) - они не поддерживаются с -Filter
.
Использование параметра -Filter
в целом все еще предпочтительнее - -Path
/ -Include
(см. Ниже) из-за его превосходящего качества. производительность (фильтрация в источнике , а не по факту в PowerShell).
Обходной путь заключается в использовании -Path
параметр , чтобы использовать сопоставление с подстановочными знаками PowerShell:
Get-ChildItem -Path (Join-Path (Get-Location) *.xls) | ForEach-Object { $_.Extension }
# Or, more simply
Get-ChildItem -Path $PWD/*.xls | ForEach-Object Extension
Примечание: При -Recurse
вместо параметра -Include
будет использоваться .
[1] Известны другие причуды:
Несколько последовательных подстановочных знаков ?
могут соответствовать именам с меньше символов.
- Например,
Get-ChildItem -Filter ??.txt
соответствует aa.txt
и неожиданно также a.txt
- Примечание. Это было временно исправлено в PowerShell Core 6.x (по состоянию на 6.2.3), но поведение возвращается к PowerShell Core 7.0.0-r c .2
Шаблон *.
соответствует файлу и каталогу без расширения имена.
Например, Get-ChildItem -File -Filter *.
находит все файлы (-File
), чьи имена не имеют расширения (например, file
); эта причуда может быть полезна тем, что это самый простой и эффективный способ найти файлы без расширений (-Path *.
не не работает, потому что он ищет имя файла буквально , оканчивающийся на .
).
Примечание. Это было временно изменено в PowerShell Core 6.x (по состоянию на 6.2.3), но поведение возвращено к PowerShell Core 7.0.
И наоборот, *.*
также включает имена файлов и каталогов без расширения.
См. этот превосходный ответ от Zenexer для предыстории и кровавых подробностей.