【发布时间】:2019-01-08 14:51:34
【问题描述】:
我想在方括号中列出所有以某些文本结尾的文件。
但是Get-ChildItem *[*、Get-ChildItem *`[* 和Get-ChildItem *``[* 都不起作用。
我怎样才能毫不费力地完成这项工作(即通过创建变量、通过管道运行其他命令等)
【问题讨论】:
标签: powershell
我想在方括号中列出所有以某些文本结尾的文件。
但是Get-ChildItem *[*、Get-ChildItem *`[* 和Get-ChildItem *``[* 都不起作用。
我怎样才能毫不费力地完成这项工作(即通过创建变量、通过管道运行其他命令等)
【问题讨论】:
标签: powershell
以下内容,包括您尝试过的其中一项,应该可以工作,但是currently[1] doesn't work due to a bug:
# SHOULD work, but CURRENTLY BROKEN:
Get-ChildItem *``[* # 1st ` is for string parsing, 2nd ` for wildcard escaping
Get-ChildItem "*``[*" # ditto, with double quotes
Get-ChildItem '*`[*' # single-quoted alternative, requires only 1 `
请注意,使用(第一个)位置参数会隐式绑定到 Get-ChildItem 的 -Path 参数。
目的是让Get-ChildItem 在参数解析后看到以下文字:*`[*,它正确地将[ 转义为`,以便将其视为文字。
顺便说一句:不带引号的*`[* 等同于双引号的"*`[*",这会产生文字*[*,因为PowerShell 的字符串解析 会解释` 并有效地删除它。
解决方法:
不要转义 [ 字符,而是将其括在 [...] 中,这是一个字符集表达式,这会导致它按字面意思匹配:
Get-ChildItem *[[]* # OK
有趣的是,通过-Include 执行过滤确实没有显示错误:
Get-ChildItem * -Include '*`[*' # OK
另一种选择是使用-Filter 代替(隐含的)-Path,如Paxz's answer 中所示,但请注意-Filter 的通配符语言不是与 PowerShell 的 相同(由 -Path 和 -Include / -Exclude 参数支持); -Filter 参数被传递给 Windows API,其通配符语言不同如下:
[...])。Filter,由于在源头进行过滤,比让 PowerShell 通过(隐含的)-Path 或 -Include 进行过滤的性能更好。另一种选择是添加另一层转义,但这是不明智的,因为一旦修复了错误,它将停止工作:
# NOT RECOMMENDED: will stop working once the bug is fixed.
Get-ChildItem '*``[*'
[1] 自 Windows PowerShell v5.1 / PowerShell Core 6.2.0-preview.3 起
【讨论】:
你必须正确使用-Filter 参数。
当您不指定参数时,就像您在示例中所做的那样,它将假定您要使用第一个参数(在本例中为 -Path,参考 Get-ChildItem Doc)。
试试这个:
Get-ChildItem -Filter "*`[*"
这为我找到了文件ad.a[s]。
您也可以将过滤器更改为:
Get-ChildItem -Filter "*`[*`]"
将其展开为右括号。
【讨论】:
Get-ChildItem "*[`[]*"。
Get-ChildItem *[[]* 即可; "*`[*" 不适用于 -Path,因为字符串解析会吃掉反引号。 '*`[*' 应该工作,但不是由于错误。
-Filter 是解决-Path 如何解析其参数的错误 的解决方法。此外,即使它在这种情况下有效,但它通常不是完全等效的解决方法,因为-Filter 通配符语言不同于 PowerShell 的通配符语言。
Get-ChildItem -Filter "*`[*" 根本不会对生成的通配符参数进行转义(在字符串扩展期间删除了反引号),并且与 Get-ChildItem -Filter *[* 相同 - 这是一种指示-Filter 以不同的方式解析其参数。