请原谅这个菜鸟问题,但我对这个问题完全感到困惑。
我有一个“存款人”目录,用户提交的文件到达该目录,并且无法控制传入的文件名。
我在 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
答案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)
}
}