当文件名包含 [方括号字符] 时,Powershell 复制/移动/重命名时会出现错误吗?

当文件名包含 [方括号字符] 时,Powershell 复制/移动/重命名时会出现错误吗?

请原谅这个菜鸟问题,但我对这个问题完全感到困惑。

我有一个“存款人”目录,用户提交的文件到达该目录,并且无法控制传入的文件名。

我在 PS 中创建了一个解析器,它非常成功地将文件(基于文件名内容)移动到适当的目的地。

除文件名包含“[”或“]”外,此方法均能正常工作。

这是“重命名”预处理器,它无法真正重命名包含任一讨厌的括号字符的文件:

 cd $folderpath
 foreach ($i in get-childitem $folderpath) {   
     if ($i.mode.substring(0,1) -ne “d”) {
        $name = $i.name.replace("[","_")
        $name = $name.replace("]","_")
        Write-Host $i -foregroundcolor “blue”       
        Write-Host $name -foregroundcolor “green”  

        Rename-Item $i $name 

     }
 }

这也适用于 ren、copy、move 及其 cmdlet 等效项

非常欢迎您提供任何见解。

提前致谢 。 。 。

答案1

除非使用-LiteralPath,否则方括号会导致字符转义的真正问题。问题来自 PowerShell 在内部多次对字符串进行转义,并使用特殊字符进行模式匹配。让 PowerShell 正确识别路径字符串中的文字方括号很复杂。

如果你使用单引号字符串,则需要括号反引号来转义它。如果你使用双引号字符串,则需要使用括号反引号来退出。

如果您正在寻找名为 的文件MyFile[1].txt,则需要使用:

'MyFile``[1``].txt'

或者:

"MyFile````[1````].txt"

是的,这很麻烦。要了解为什么会这样,你必须知道发生了什么。通过逆向思考很容易做到这一点。

假设您想要获取一个名为的文件[ab].txt

通配符模式匹配Get-ChildItem意味着如果它获取[ab].txt路径,那么它将查找名为a.txt 和 的文件b.txt。因此,如果我们想要匹配文字,我们必须使用转义字符(反引号)来转义括号。这为我们提供了要用于 filespec 的[ab].txt实际字符串:Get-ChildItem

`[ab`].txt

但是,我们必须将此文件规范作为字符串传递。这意味着Get-ChildItem将转义这些反引号,但这不是我们想要的!我们需要文字反引号。因此,我们在字符串中使用反引号转义反引号,以确保Get-ChildItem使用正确的文件规范:

'``[ab``].txt'

如果我们想使用双引号字符串,那么我们必须转义每个反引号再次,因为双引号字符串将取消转义该字符串。这就是最终结果:

"````[ab````].txt"

这就是为什么许多采用文件规范的 PowerShell 函数都有该-LiteralPath选项的原因。

答案2

RenameItem没有-LiteralPathfor一些愚蠢的理由(链接失效)。*

Move-Item -LiteralPath $i -destination $name

*该语言的共同设计者的借口。

-LiteralPath 出现已被添加。

答案3

这样最终达到了预期的效果:

foreach ($i in get-childitem $folderpath) {
  if ($i.mode.substring(0,1) -ne “d”) {
    $name = $i.name.replace("[","_")
    $name = $name.replace("]","_")

   Write-Host $name -foregroundcolor “green”    
   [System.IO.File]::Move($folderPath+"\"+$i, $folderPath+"\"+$name) 
  }
}

相关内容