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

TTr*_*itt 11 powershell filenames

请原谅一个菜鸟问题,但我完全被这个问题搞糊涂了。

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

我在 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 

     }
 }
Run Code Online (Sandbox Code Playgroud)

这对于 ren、copy、move 及其 cmdlet 等效项也失败

您可以提供任何见解将是最受欢迎的。

提前致谢 。. .

Bac*_*its 13

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

如果您使用单引号字符串,括号需要两个反引号来转义它。如果您使用双引号字符串,括号需要四个反引号来转义它。

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

'MyFile``[1``].txt'
Run Code Online (Sandbox Code Playgroud)

或者:

"MyFile````[1````].txt"
Run Code Online (Sandbox Code Playgroud)

是的,这是一种痛苦。要了解它为什么会这样做,您必须知道发生了什么。通过向后工作很容易做到这一点。

假设您想要获取一个字面名为[ab].txt.

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

`[ab`].txt
Run Code Online (Sandbox Code Playgroud)

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

'``[ab``].txt'
Run Code Online (Sandbox Code Playgroud)

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

"````[ab````].txt"
Run Code Online (Sandbox Code Playgroud)

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


Den*_*son 6

RenameItem没有一个-LiteralPath出于某种愚蠢的原因*

Move-Item -LiteralPath $i -destination $name
Run Code Online (Sandbox Code Playgroud)

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