ls *.gif | Foreach { $newname = $_.Name -replace '\[','' -replace '\]',''
write-host $_.Name $newname
move-Item -Path $_.Name -Destination $newname; }
ls *.gif
因此,在尝试帮助某人使用[]重命名文件时,我发现move-item在循环中不起作用。它似乎在循环之外工作得很好。
想法?
答案 0 :(得分:7)
更新:根据下面的评论,我想澄清一下:文件名中的特殊字符要求您使用-LiteralPath参数。 -Path无法处理这些字符。在循环之外,-Path有效,因为你使用`来转义特殊字符。在走过一个集合时,这是不可能的。
在循环中,您需要使用-LiteralPath参数而不是-Path。
-LiteralPath <string[]>
Specifies the path to the current location of the items. Unlike Path, the value of
LiteralPath is used exactly as it is typed. **No characters are interpreted as
wildcards. If the path includes escape characters, enclose it in single quotation
marks.** Single quotation marks tell Windows PowerShell not to interpret any
characters as escape sequences.
所以,这将是:
GCI -Recurse *.txt | % { Move-Item -LiteralPath $_.FullName -Destination "SomenewName" }
答案 1 :(得分:3)
如果您使用PowerShell的管道绑定功能,则可以使这更加简单,并且无需显式Foreach-Object
,例如:
ls *.gif | Move-Item -Destination {$_ -replace '\[|\]',''} -WhatIf
这是有效的,因为LiteralPath
参数设置为绑定ByPropertyName
。但是您可能想知道,它从Get-ChildItem
(别名ls)的输出中获取了名为“LiteralPath”的属性。好吧,它没有找到该属性名称,但是LiteralPath
参数定义的别名为PSPath
,它确实存在于Get-ChildItem
输出的每个对象上。这就是它与LiteralPath
参数的联系。这里的另一个速度提示是因为Destination
参数也是管道绑定(ByPropertyName),您可以使用scriptblock
来提供值。在该脚本块中,您可以访问管道对象。
在scriptblock内部,它使用-replace
运算符根据原始全名提出新名称。虽然在这种情况下我可以使用$_.FullName
甚至$_.Name
(假设您想要在同一目录中重命名文件),但我只使用$_
。由于-replace
是一个字符串运算符,因此在使用之前它会将$_
强制转换为字符串。你可以通过执行来看看它会是什么:
ls *.gif | Foreach {"$_"}
在这种情况下,这是完整的路径,但你必须要小心,因为你并不总是得到完整的路径,例如:
ls | Foreach {"$_"}
只显示文件名。在你的例子中(重命名为相同的目录)这没关系,但在其他情况下确实如此。在脚本中明确地使用$_.Name
或$_.FullName
可能是一个好习惯,但是当在控制台上破解这些东西时,我倾向于只使用$_
。俗话说:这是一根尖锐的棍子,不要捅你的眼睛适用于此。 : - )
答案 2 :(得分:0)
您可以在this Microsoft article上的路径字符串中找到有关“[
”角色的“官方”信息。
或者在google中查找:Windows PowerShell本周提示:“按字面意思拍摄内容(如文件路径)”。
我不清楚的唯一提示是Rename-Item
不支持LiteralPath
,我们可以使用Move-Item
重命名文件或目录。
JP
答案 3 :(得分:0)
这对我有用(至少在我的情况下。
Move-Item -literalpath $_.FullName -Destination ( ( ( (Join-Path -Path (Get-Location) -ChildPath $_.BaseName) -replace "\[","`[") -replace "\]","`]") )
有数百部电影及其关联的字幕存储没有文件夹。决定将每部电影和字幕放在自己的文件夹中
Get-ChildItem -File | %
{
if(Test-Path -LiteralPath ( Join-Path -Path (Get-Location) -ChildPath $_.BaseName ))
{
Move-Item -literalpath $_.FullName -Destination ( ( ( (Join-Path -Path (Get-Location) -ChildPath $_.BaseName) -replace "\[","`[") -replace "\]","`]") )
}
else
{
New-Item ( Join-Path -Path (Get-Location) -ChildPath $_.BaseName ) -ItemType Directory
Move-Item $_ -Destination ( Join-Path -Path (Get-Location) -ChildPath $_.BaseName )
}
}