powershell - 忽略 Powershell 字符串中的通配符 []

标签 powershell

我有一个 Powershell 脚本,它采用文件名作为输入。

param([string]$folder, [string]$input_filename)
$logfile=$folder + "\duplicate.log"
Write-Output "`nScript: `n$transformation_filename`nLogfile: " | Out-file $logfile -Append

这对于大多数文件名都适用,但当文件名或文件夹名称包含 [] 时,它就会崩溃。

dupfile.ps1 "C:\foldername [w]" "filename.xml"

第 3 行抛出此错误: 无法执行操作,因为通配符路径 C:foldername [w]\duplicate.log 未解析为文件。

因此必须更字面地对待变量。

$logfile='$folder' + "\duplicate.log"

不,这太字面意思了。

$logfile="$folder" + "\duplicate.log"

不,同样的错误。

如何告诉 Powershell 插入变量值,但不要尝试将该值中的任何内容解释为通配符?

编辑:我正在使用 Powershell 5。 我的 dupfile.ps1 仅包含上面的 3 行。 从 PS shell 使用此命令来运行脚本: C:_SCRIPTS_\dupfile.ps1 "C:\foldername [w]""test.txt"

如果可以的话,我还有一个补充。我有几行将错误消息重定向到日志文件。

Copy-Item -LiteralPath  $inputPath -Destination $outputPath 2>&1|%{ "$_" } >>$logfile

重定向再次经过 []。我认为我不能在这里使用 -LiteralPath。

最佳答案

tl;博士

确保重定向操作中的文件路径参数 $var 得到处理
> $var/>> $var 字面上如果它包含[],请使用
|输出文件 -LiteralPath $var/|改为 Out-File -LiteralPath $var -Append

Copy-Item -LiteralPath $inputPath -Destination $outputPath 2>&1 |
  ForEach-Object { "$_" } |
  Out-File -LiteralPath $logfile # literal alternative to >> $logfile

就您的情况而言,您可能必须将其与 redirection 结合使用。为了确保除了成功之外还有其他output stream目标:

# Literal equivalent of *>> $logfile
... *>&1 | Out-File -LiteralPath $logfile -Append

不幸的是,仅捕获给定的其他流会变得很棘手,因为您需要使用适当的-*Variable通用参数,例如common -ErrorVariable parameter :

# Literal equivalent of 2>> $logfile
... -ErrorVariable errs
$errs | Out-File -LiteralPath $logfile -Append

警告:

  • 尝试通过转义文字路径来绕过上述解决方案是很诱人的,这样当它被解释为通配符时,就会按字面意思处理,使用[WildcardPattern]::Escape() .

  • 但是,从 PowerShell 7.2.6 开始,这无法按预期工作,因为文字路径的转义形式随后将用作文字文件路径 - 请参阅 GitHub issue #9475以及关于 >/>>, ... 是否应该将其参数视为通配符的讨论。

# !! Arguably SHOULD work, but doesn't as of 7.2.6:
# The file that is created is LITERALLY named for the ESCAPED form:
#  `[1`].txt
'hi' > ([WildcardPattern]::Escape('[1].txt'))

背景信息:

PowerShell provider-Path (-FilePath) 参数 cmdlet 需要 wildcard expressions用于通过名称或路径模式定位文件系统项。此参数隐式由第一个位置参数定位,即,如果您没有显式命名目标参数 - 例如,Get-ChildItem foo与 Get-ChildItem -Path foo 隐式相同。

  • 令人惊讶的是,这不仅仅适用于文件读取 cmdlet(例如 Get-ChildItemGet-Content ),还可以用于文件写入 cmdlet(例如,Set-ContentOut-File)。

    • 请注意,由于历史原因,名为 -Path 的参数在 Out-File 中被称为 -FilePath。在PowerShell(核心)7+ 中,为了保持一致性,-Path 被引入作为别名
  • 可以说,在文件编写/创建 cmdlet 中,这种行为不合适 - 考虑到您通常确切地知道什么您想要定位的 >literal 路径 - 有几个 GitHub 问题讨论了这个问题;所有相关讨论的概述可以在 this comment on GitHub issue #17106 中找到。 .

为了按照字面意义(逐字)处理此类参数,您必须
改用-LiteralPath参数

实际上,> $var>> $var| 的别名。 Out-File -FilePath $var| Out-File -FilePath $var -Append,这意味着 $var 被解释为通配符。

使用带有 -LiteralPath 的显式 Out-File 调用(如顶部所示)可以避免此问题。

关于powershell - 忽略 Powershell 字符串中的通配符 [],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73331921/

相关文章:

regex - 正则表达式替换以某个子字符串开头的所有单词的所有出现

visual-studio - 使用 PowerShell 打开文件

PowerShell - 转置哈希表的结果

windows - 我可以只在 ebextensions 中包含一个脚本而不必构建一个吗?

powershell - 将Get-Childitem过滤为CSV的内容

c++ - 使用 C/C++ 通过管道向/从 Powershell 设置 UTF-8 输入和获取 UTF-8 输出

powershell - 使用 PowerShell 替换文件中的字符串

powershell - 根据属性的数量将对象的子集传递到管道中?

wcf - 使用 PowerShell 的 New-WebServiceProxy 访问 net.tcp 端点

powershell - 父PowerShell控制台似乎可以控制子PowerShell控制台I/O