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

时间:2020-02-11 14:24:19

标签: powershell

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

为什么以下行无法正常运行?我看到了.xls,.xlsx和.xlsm结果。

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

2 个答案:

答案 0 :(得分:1)

-Filter参数的通配符匹配不是由PowerShell执行的,而是由执行的,它会传递给文件系统提供程序,最后传递给Windows API。 在该处执行的匹配会产生许多遗留的行为和怪癖,包括您看到的那些:

  • Windows PowerShell 中, -Filter *.xls的行为类似于-Filter *.xls* 。因此,例如-Filter *.xlsfoo.xlsfoo.xlsx都匹配;之所以会这样,是因为 8.3(短)文件名也被 在幕后匹配;例如,foo.xlsx的8.3文件名看起来像FOO~1.XLS;注意.xlsx.XLS的截断(和大写)。

  • 虽然短名称匹配行为在PowerShell [Core] v6 + 中不再发生,但幸运的是,其他遗留的古怪现象仍然存在 [1] < / sup>,以及最明显的区别(不会消失): 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-rc.2起已恢复。
  • 模式*.与无扩展名的文件和目录名称匹配。

    • 例如,Get-ChildItem -File -Filter *.查找名称不带扩展名的所有文件(-File)(例如file);这个怪癖实际上是有用的,因为它是查找无扩展名文件的最简单且性能最佳的方式(-Path *.不能 起作用,因为它会查找文件名字面意思.结尾)。

    • 注意:在PowerShell Core 6.x(从6.2.3版本开始)中,这是临时更改,但是从PowerShell Core 7.0开始,行为已恢复。

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

有关背景故事和血腥细节,请参见this excellent answerZenexer

答案 1 :(得分:0)

-filter与文件名的简短版本匹配。这已经在其他地方讨论过了。在Powershell 6中已解决。

echo hi > file.xlsx
dir -filter *.xls


    Directory: C:\users\js\foo


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/11/2020   9:54 AM              4 file.xlsx


cmd /c dir /x

 Volume in drive C is DISK
 Volume Serial Number is A11A-AA11

 Directory of C:\users\js\foo

02/11/2020  09:54 AM    <DIR>                       .
02/11/2020  09:54 AM    <DIR>                       ..
02/11/2020  09:54 AM                 4 FILE~1.XLS   file.xlsx
               1 File(s)              4 bytes
               2 Dir(s)   3,380,170,752 bytes free