使用 -Filter 参数通常比 -Path/-Include 更可取>(见下文)由于其卓越的性能(过滤发生在源头,而不是事后在 PowerShell 中).解决方法是使用 -Path 参数,以便使用 PowerShell 的 通配符匹配:Get-ChildItem -Path (Join-Path (Get-Location) *.xls) |ForEach-Object { $_.Extension }# 或者,更简单Get-ChildItem -Path $PWD/*.xls |ForEach-Object 扩展注意:如果使用 -Recurse,您将改用 -Include 参数.[1] 其他值得注意的怪癖:多个连续的 ? 通配符可以匹配较少个字符的名称.例如,Get-ChildItem -Filter ??.txt 匹配 aa.txt 并且意外地也匹配 a.txt注意:这在 PowerShell Core 6.x 中暂时修复(从 6.2.3 开始),但从 PowerShell Core 7.0.0-rc.2 开始,该行为又恢复了模式 *. 匹配无扩展名的文件和目录名称.例如,Get-ChildItem -File -Filter *. 查找名称没有扩展名(例如,-File)的所有文件(-File)>文件);这个怪癖实际上很有用,因为它是定位无扩展名文件的最简单和性能最好的方法(-Path *. 确实不起作用,因为它看起来对于以 . 结尾的文件名字面意义.注意:这在 PowerShell Core 6.x(自 6.2.3 起)中暂时发生了变化,但该行为从 PowerShell Core 7.0 起又恢复了.立>相反,*.* 也包括无扩展名的文件和目录名称.请参阅这个出色的答案">Zenexer 了解背景故事和血腥细节.I have a folder that contains both .xls, .xlsx and .xlsm files, and would like to filter just the .xls files.Why is the following line not working as I'd expect it to? I see .xls, .xlsx and .xlsm results.Get-ChildItem $(Get-Location) -Filter *.xls | ForEach-Object { $_.Extension } 解决方案 The -Filter parameter's wildcard matching is not performed by PowerShell, it is passed through to the filesystem provider and ultimately the Windows API.The matching performed there is burdened with many legacy behaviors and quirks, including the one you saw:In Windows PowerShell, -Filter *.xls effectively behaves like -Filter *.xls*. Therefore, -Filter *.xls matches both foo.xls and foo.xlsx, for instance; this happens, because the 8.3 (short) file names are also being matched behind the scenes; for instance, foo.xlsx's 8.3 file name looks something like FOO~1.XLS; note the truncation (and capitalization) of .xlsx to .XLS.While the short-name matching behavior no longer occurs in PowerShell [Core] v6+, fortunately, other legacy quirks persist, as does the most notable difference (which won't go away): only PowerShell wildcard expressions (see about_Wildcards) support character ranges / sets via [...] (e.g., [a-z]) - they're not supported with -Filter.Use of the -Filter parameter is in general still preferable to -Path / -Include (see below) due to its superior performance (filtering happens at the source, instead of after the fact in PowerShell).The workaround is to use the -Path parameter in order to use PowerShell's wildcard matching:Get-ChildItem -Path (Join-Path (Get-Location) *.xls) | ForEach-Object { $_.Extension }# Or, more simplyGet-ChildItem -Path $PWD/*.xls | ForEach-Object ExtensionNote: With -Recurse you'd use the -Include parameter instead.[1] Notable other quirks:Multiple consecutive ? wildcards can match names with fewer characters.E.g., Get-ChildItem -Filter ??.txt matches aa.txt and unexpectedly also a.txtNote: This was temporarily fixed in PowerShell Core 6.x (as of 6.2.3), but the behavior is back as of PowerShell Core 7.0.0-rc.2Pattern *. matches extension-less file and directory names.E.g., Get-ChildItem -File -Filter *. finds all files (-File) whose names do not have an extension (e.g., file); this quirk can actually be useful, in that it is the simplest and best-performing way to locate extension-less files (-Path *. does not work, because it looks for a file name literally ending in a .).Note: This was temporarily changed in PowerShell Core 6.x (as of 6.2.3), but the behavior is back as of PowerShell Core 7.0.Conversely, *.* includes extension-less file and directory names as well.See this excellent answer by Zenexer for the backstory and the gory details. 这篇关于在 Get-ChildItem 中指定 *.xls 过滤器也会返回 *.xlsx 结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-28 18:42