正如提到另外一个问题,如果你尝试做一个Get-ChildItem -filter ...命令你比,如果你使用的更有限-include替代-filter.我想阅读文件系统提供程序的过滤语法的官方文档,但经过半小时的搜索后,我仍然没有找到它们.谁知道在哪里看?
Zen*_*xer 17
tl; dr -Filter使用.NET的实现FsRtllsNameInExpression,MSDN上记录了该实现以及基本模式匹配信息.出于兼容性原因,该算法不直观,您应该避免使用此功能.此外,.NET在其实现中存在许多错误.
-Filter不使用由PowerShell中提供的过滤系统-即,它不使用由所述的过滤系统Get-Help about_Wildcard.相反,它将过滤器传递给Windows API.因此,过滤的工作方式与使用Windows API的任何其他程序相同,例如cmd.exe.
相反,PowerShell使用类似FsRtlIsNameInExpression算法进行-Filter模式匹配.该算法基于旧的MS-DOS行为,因此它充满了为传统目的而保留的警告.通常说它有三个常见的特殊字符.确切的行为很复杂,但它或多或少如下:
*:匹配任意数量的字符(包含零)?:匹配一个字符,不包括名称中的最后一个句点.:如果模式中的最后一个句点,则锚定到文件名中的最后一个句点,如果没有句点,则锚定到文件名的结尾; 也可以匹配字面时期为了使事情变得更复杂,Windows添加了三个额外的特殊字符,其行为与旧的MS-DOS特殊字符完全相同.原始特殊字符现在具有稍微不同的行为,以考虑更灵活的文件系统.
"相当于MS-DOS . (DOS_DOT和ANSI_DOS_DOTntifs.h)<相当于MS-DOS ? (DOS_QM和ANSI_DOS_QMntifs.h)>相当于MS-DOS * (DOS_STAR和ANSI_DOS_STARntifs.h)不少人士似乎扭转<和>.可怕的是,微软将它们混淆在.NET实现中,这意味着它们在PowerShell中也是相反的.此外,所有三个兼容性通配符都不可用-Filter,因为System.IO.Path错误地将其"<>视为无效的非通配符.(它允许.*?.)这有助于 - 过滤器不完整,不稳定和有缺陷的概念. 您可以在GitHub上看到.NET的(错误)算法实现.
算法对8.3兼容性文件名的支持也更加复杂,否则称为"短"文件名.(您之前可能已经看过它们了;它们看起来像SOMETH~1.TXT:)如果文件的完整文件名或短文件名匹配,则文件与模式匹配. FrankFranchise在他的回答中提供了有关此警告的更多信息.
以前链接的MSDN文章FsRtlIsNameInExpression提供了有关Windows文件名模式匹配的最新文档,但它并不特别详细.有关如何在MS-DOS上使用匹配以及它如何影响现代匹配的更全面的解释,这篇MSDN博客文章是我发现的最佳来源.这是基本的想法:
? 匹配任何单个字符,但扩展名中的空格除外. 用空格填充前8个字节的剩余部分,然后前进到第9个字节(扩展的开始)* 会用问号填充当前部分(正文或扩展名)的其余部分,然后前进到下一部分(或模式的结尾)转换看起来像这样:
11
User 12345678901
------------ -----------
ABC.TXT > ABC TXT
WILDCARD.TXT > WILDCARDTXT
ABC.??? > ABC ???
*.* > ???????????
*. > ????????
ABC. > ABC
Run Code Online (Sandbox Code Playgroud)
推断这与现代文件系统一起使用是一个不直观的过程.例如,获取如下目录:
Name Compat Name
-----------------------------------------------
Apple1.txt APPLE1 .TXT
Banana BANANA .
Something.txt SOMETH~1.TXT
SomethingElse.txt SOMETH~2.TXT
TXT.exe TXT .EXE
TXT.eexe TXT~1 .EEX
Wildcard.txt WILDCARD.TXT
Run Code Online (Sandbox Code Playgroud)
我已经在Windows 10上对这些通配符进行了相当多的测试,并且得到了非常不一致的结果,尤其是DOS_DOT(").如果您从命令提示符自己测试这些,您可能需要转义它们(例如,dir ^>^"^>在cmd.exe中模拟MS-DOS *.*).
*.* (everything)
<"< (everything)
* (everything)
< Banana
. (everything)
" (everything)
*. Banana
<" Banana
*g.txt Something.txt
<g.txt Something.txt
<g"txt (nothing)
*1.txt Apple1.txt, Something.txt
<1.txt Apple1.txt, Something.txt
<1"txt (nothing)
*xe TXT.eexe, TXT.exe
<xe (nothing)
*exe TXT.eexe, TXT.exe
<exe TXT.exe
??????.??? Apple1.txt, Asdf.tx, Banana, TXT.eexe, TXT.exe
>>>>>>.>>> Apple1.txt, Asdf.tx, TXT.eexe, TXT.exe
>>>>>>">>> Banana
????????.??? (everything)
>>>>>>>>.>>> (everything except Banana)
>>>>>>>>">>> Banana
???????????.??? (everything)
>>>>>>>>>>>.>>> (everything except Banana)
>>>>>>>>>>>">>> Banana
?????? Banana
>>>>>> Banana
??????????? Banana
>>>>>>>>>>> Banana
???????????? Banana
???? (nothing)
>>>> (nothing)
Banana??. Banana
Banana>>. Banana
Banana>>" Banana
Banana????. Banana
Banana>>>>. Banana
Banana>>>>" Banana
Banana. Banana
Banana" Banana
*txt Apple1.txt, Something.txt, SomethingElse.txt, Wildcard.txt
<txt Apple1.txt, Something.txt, SomethingElse.txt, Wildcard.txt
*t Apple1.txt, Something.txt, SomethingElse.txt, Wildcard.txt
<t (nothing)
*txt* Apple1.txt, Something.txt, SomethingElse.txt, TXT.eexe, TXT.exe, Wildcard.txt
<txt< Apple1.txt, Something.txt, SomethingElse.txt, Wildcard.txt
*txt< Apple1.txt, Something.txt, SomethingElse.txt, Wildcard.txt
<txt* Apple1.txt, Something.txt, SomethingElse.txt, TXT.eexe, TXT.exe, Wildcard.txt
Run Code Online (Sandbox Code Playgroud)
注意:在编写时,WINE的匹配算法在测试这些"陷阱"时会产生明显不同的结果.用WINE 1.9.6测试.
正如您所看到的,向后兼容的MS-DOS通配符是模糊和错误的. 甚至微软也至少错误地实现过一次,目前还不清楚他们目前在Windows中的行为是否是故意的.行为"似乎是完全随机的,我期望最后两个测试的结果被交换.
几乎什么都没有-filter.
当你做的时候有一点点Get-Help Get-ChildItem -full,但我相信你已经看过了.Powershell博客上还有一篇文章.都不举例.
我能找到的最好的例子就是这个,它只是演示了过滤器是一个字符串,提供者用它来返回它本来会返回的子集,而且它甚至不是直接演示-filter而是简单地使用它.但是,它比其他链接更好一瞥.
但是,因为提供程序在结果返回到cmdlet之前进行过滤,所以有一些警告.例如,如果我想递归发现,以"test"开头的所有文件和目录,我就不会想开始这样的:
Get-ChildItem -filter 'test*' -recurse
Run Code Online (Sandbox Code Playgroud)
这将在返回递归的任何内容之前过滤当前目录中的所有结果.如果我有一个以"test"开头的目录,它将递归该目录(因为提供程序会将其返回到cmdlet),但没有其他目录.
如示例所示,它可以解决某些提供程序中的属性.在FileSystem提供程序中,您可能只能在目录或文件名上使用通配符匹配字符串(leaf,而不是完全限定).
| 归档时间: |
|
| 查看次数: |
10877 次 |
| 最近记录: |