我有一些文件名称中带有“元字符”,例如括号:
'test[txt].0', 'test[xml].0', 'test[xml].1' | % {New-Item $_} | Out-Null
我可以使用 glob 获取这些文件:
Resolve-Path -Path 'test*'
Path
----
C:\test[txt].0
C:\test[xml].0
C:\test[xml].1
或者使用反引号转义符:
Resolve-Path -Path 'test`[xml`].0'
Path
----
C:\test[xml].0
test[xml].
但我无法获得以使用反引号转义符和“通配符”开头的那些:
Resolve-Path -Path 'test`[xml`].*'
-Path
正确的用法是什么?
为了在 PowerShell 中使用单个 glob 匹配以 开头的文件
test[xml]
,您需要正确地转义括号。在 PowerShell 中,反引号 (`) 用作转义字符。由于需要转义括号,因此由于存在错误,您应该使用双反引号来转义每个括号。希望他们能在即将推出的版本中修复它。
要解决此错误,一个可能的解决方案是避免使用任何反引号转义序列;只需将开括号括在括号内:
备注:此处无所谓是否
test[[]xml].*
用引号、单引号或双引号前言:
如果路径只是包含和字符的文字
[
]
路径,则正确的解决方案是使用-LiteralPath
参数而不是(可能是位置隐含的)-Path
参数,如此答案中所述;在PowerShell(核心)7-LiteralPath
中可以缩写为。-lp
在当前情况下,路径是根据 PowerShell通配符 模式设计的。
您看到的是一个长期存在的错误,它影响所有提供程序cmdlet(例如
Get-ChildItem
,包括),于 2018 年在GitHub 问题 #7999中首次报告,标题为“反引号转义不一致”,它抓住了问题的要点:有时,出于没有明显的原因,您必须双重转义
[
和]
字符,以便它们按字面意思处理,而不是作为通配符元字符处理,即逐字``[
和``]
另外,有时您只需 转义即可
[
(而不是同时转义]
),例如在当前的情况下(应该是这样,因为]
单独的不是元字符):这个错误的具体变化是,由于转义
[
(和可能的)与(未转义)或]
相结合,意外地需要双重转义。*
?
总而言之:
由于
`
,所谓的反引号也在可扩展(插值)字符串中充当转义字符(与逐字字符串相反"..."
),所以每个传递给目标命令的字符串都必须再次加倍;这也适用于裸字参数(未加引号的命令参数),它们被隐式地视为可扩展字符串。'...'
`
因此,上述命令的等效内容是:
警告:
虽然上述解决方法及其语法变化目前有效,但如果在未来的 PowerShell 7 版本中修复该错误,它们将会失效。
请参阅下一部分以了解面向未来的解决方法。
替代的、面向未来的解决方法,其中转义按预期工作:
正如您自己的回答所示,最简单的解决方法是制作字符集
[
的一部分(),其中不需要转义;也就是说,使用:[...]
[[]
`
不涉及 -escaping,所以这具有额外的优势,即不需要根据是否使用引用/裸词'...'
来改变模式。"..."
在后处理步骤中使用通配符匹配运算符进行过滤
-like
;虽然Where-Object
效率较低,但其工作原理是可以预见的:在 的上下文中
Get-ChildItem
,如果通配符元字符仅限于最后一个路径组件,则可以通过-Filter
参数表达该组件,其中[
和]
不需要转义:-Filter
通常与 PowerShell 自己的通配符不同:除了-Filter
不支持字符集和范围(例如[abc]
或[a-c]
) - 这就是为什么[
和]
不需要转义 - 匹配具有向后兼容的遗留怪癖 - 有关详细信息,请参阅此答案。