如何使用Invoke-WebRequest的-OutFile参数对文件路径中的方括号进行转义

时间:2019-04-26 14:22:38

标签: powershell escaping glob

在与[1]File[1].txt参数一起使用的Invoke-WebRequest文件名中包含-OutFile之类的错误Cannot perform operation because the wildcard path File[1].txt did not resolve to a file.

这是由here中记录的行为引起的。

对于其他cmdlet,您将使用-LiteralPath强制按原样使用路径,但在这种情况下,这不是一个选择。

我尝试用`或[来转义]\字符,但仍然会出现相同的错误。

为简化测试,您可以使用Out-FileTest-Path等重现相同的问题。

#Fails
Out-File -FilePath "file[1].txt"
Out-File -FilePath "file`[1`].txt"
Out-File -FilePath "file\[1\].txt"

#Succeeds
Out-File -LiteralPath "file[1].txt"

#Fails
Test-Path -Path "file[1].txt"

#Succeeds
Test-Path -LiteralPath "file[1].txt"

如何在-Path-FilePath-OutFile等中转义用于表示通配符的字符,以便它们像用{{1}指定字符串那样起作用},因为-LiteralPath无法与-LiteralPath一起使用?

1 个答案:

答案 0 :(得分:1)

  • 很遗憾,如您所述,Invoke-WebRequestInvoke-RestMethod尚不支持
    -LiteralPath,但是linked GitHub issue显示将添加支持将来。

  • 转义[]字符转换为`[`],以便对它们进行字面意义被解释为带有-Path-FilePath)的通配符表达式时,由于 bug,目前只有 half 起作用在底部讨论:

    • 执行转义可确保-Path参数接受路径(命令不再中断)...

    • ...但是在文件的创建上,错误地将转义的表示用作 literal 文件名-参见底部。

暂时

解决方法

  • 使用下面详细说明的转义...
  • ...,然后重命名该文件以删除不需要的`字符。
# Literal input path.
$literalOutFile = 'file[1].txt'

# Create escaped wildcard-pattern representation that -OutFile accepts.
$escapedOutFile = [WildcardPattern]::Escape($literalOutFile)

# Call Invoke-RestMethod -OutFile with the escaped representation.
'hi' |  Out-File -FilePath $escapedOutFile

# # Rename the resulting file to compensate for the bug discussed below.
# # !! Note how the *escaped* path must be passed to -LiteralPath, because
# # !! the bug causes the output file to be created with the *escaped* name.
Rename-Item -LiteralPath $escapedOutFile ($escapedOutFile -replace '`')

修复错误后,此代码应继续工作-假设您的文件名从不包含嵌入式文字`-字符。 -尽管Rename-Item通话将变为无人操作。


转义[文字]路径以用作通配符模式:

使用以下任何 string-literal 表示形式,这些表示形式最终会产生具有逐字内容file`[1`].txt的相同字符串,当将其解释为通配符表达式,等于文字字符串file[1].txt转义

  • 'file`[1`].txt'
  • "file``[1``].txt"
  • file``[1``].txt

要以编程方式创建转义的 ,请使用:

$literalName = 'file[1].txt'
$escapedName = [WildcardPattern]::Escape($literalName) # -> 'file`[1`].txt'

重要的是,目标cmdlet将[])参数中的`-Path视为-FilePath转义他们将被逐字对待。

如果您使用"..."引号或未引号参数(其行为就像是用"..."括起来一样),则PowerShell的 string 会被解析会妨碍您:`也用作可扩展字符串("...")中的转义字符,因此,要使` 通过,您必须进行转义它本身就是``

  • 否则`[中的"..."会变成[-`被“吃掉”-因为`[是逃脱的{{1}从[的角度来看,}转义一个不需要转义的字符会变成该字符;简而言之:"...""file`[1`].txt"都变成普通的file`[1`].txt,就像您从未使用过file[1].txt一样。

相反,`字符在`引用的字符串中按原样使用,不需要转义。


许多'...'的cmdlet的文件创建行为有问题:

上述 bug -在文件 creation 中,转义的表示被错误地用作文字文件名-影响 cmdlet ,不幸的是:也就是说,它们在创建时意外地保留了转义模式中的-Path个字符一个文件,因此,通过指定` [1 -Path 'file,您将得到一个文件名为].txt'的文件。

幸运的是,大多数cmdlet都支持file`[1`].txt,因此无论如何使用-LiteralPath都是更好的选择,并且避免了此错误。

一些受影响的cmdlet:

  • -LiteralPath file[1].txtInvoke-WebRequest

  • Invoke-RestMethod ,因此还有重定向运算符Out-File> ,它们有效地调用了>>在幕后。

    • 请注意,Out-FileSet-Content不会出现此问题。
  • 所有(?)Add-Content cmdlet。

  • 其他?

该错误已在this GitHub issue中报告。