powershell - 在 Get-ChildItem 中指定 *.xls 过滤器也会返回 *.xlsx 结果

标签 powershell

我有一个包含 .xls、.xlsx 和 .xlsm 文件的文件夹,并且想仅过滤 .xls 文件。

为什么下面的行没有像我预期的那样工作?我看到 .xls、.xlsx 和 .xlsm 结果。

Get-ChildItem $(Get-Location) -Filter *.xls | ForEach-Object { $_.Extension }

最佳答案

-Filter 参数的通配符匹配由 PowerShell 执行,它会传递到文件系统提供程序并最终传递到 Windows API。 那里执行的匹配存在许多遗留行为和怪癖,包括您所看到的:

  • Windows PowerShell 中,-Filter *.xls 的有效行为类似于 -Filter *.xls *。因此,例如,-Filter *.xls 会匹配 foo.xlsfoo.xlsx;发生这种情况是因为8.3(短)文件名在幕后进行匹配;例如,foo.xlsx 的 8.3 文件名类似于 FOO~1.XLS;请注意 .xlsx.XLS 的截断(和大写)。

  • 虽然 PowerShell [Core] v6+ 中不再出现短名称匹配行为,但幸运的是,其他遗留问题依然存在[1],最显着的区别(不会消失):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 参数如果没有-Recurse-Include(和-Exclude)的行为不直观,不幸的是 - 请参阅 this answer 的底部部分.


[1]其他值得注意的怪癖:

  • 多个连续的?通配符可以匹配具有更少个字符的名称。

    • 例如,Get-ChildItem -Filter ??.txt 匹配 aa.txt 并且意外地也匹配 a.txt
  • 模式 *. 匹配无扩展名的文件和目录名称。

    • 例如,Get-ChildItem -File -Filter *. 查找名称没有扩展名的所有文件 (-File)(例如 文件);这个怪癖实际上很有用,因为它是定位无扩展名文件的最简单且性能最好的方法(-Path *. 确实不起作用,因为它看起来对于以 . 结尾的文件名。

    • 注意:这在 PowerShell Core 6.x 中暂时发生了变化(自 6.2.3 起),但该行为自 PowerShell Core 7.0 起又恢复了。

  • 相反,*.* 也包括无扩展名的文件和目录名称。

参见this excellent answer通过 Zenexer了解背景故事和血淋淋的细节。

关于powershell - 在 Get-ChildItem 中指定 *.xls 过滤器也会返回 *.xlsx 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60171057/

相关文章:

powershell - 如何在 Powershell 中显示动态参数的 .PARAMETER 帮助消息?

PowerShell ForEach-Object 消除

powershell - 矢量粉碎保护已启用PowerShell PowerShell

powershell - 在Powershell模块功能中发出错误的正确方法是什么?

powershell - 根据输入构建命令参数

sql - 如何在 "SQL Server Maintenance"计划结束后运行程序或 PowerShell 脚本?

powershell - 如果为真则需要检查帐户是否存在如果为假则跳过创建帐户

string - powershell-删除包含换行符和空格的字符串

powershell - 在 switch 语句中分配变量

powershell - 如何使用 PowerShell 将 UTC 转换为 EST