我正在尝试执行以下操作:
Rename-Item c:\misc\*.xml *.tmp
我基本上想将目录中每个文件的扩展名更改为.tmp
而不是.xml
. 我似乎无法在 PowerShell 中找到直接的方法来执行此操作。
我正在尝试执行以下操作:
Rename-Item c:\misc\*.xml *.tmp
我基本上想将目录中每个文件的扩展名更改为.tmp
而不是.xml
. 我似乎无法在 PowerShell 中找到直接的方法来执行此操作。
Rename-Item
从使用命令检索的帮助文档中的示例 4 中:
get-help Rename-Item -examples
例子:
Get-ChildItem *.txt| Rename-Item -NewName { $_.Name -replace '\.txt','.log' }
请注意帮助文档中对替换命令中的转义反斜杠的解释,因为它使用正则表达式来查找要替换的文本。
为确保 regex-replace
运算符仅匹配字符串末尾的扩展名,请包含 regex end-of-string character $
。
Get-ChildItem *.txt | Rename-Item -NewName { $_.Name -replace '\.txt$','.log' }
这解决了@OhadSchneider 在评论中提到的情况,我们可能有一个名为的文件lorem.txt.txt
,我们希望以lorem.txt.log
而不是lorem.log.log
.
现在正则表达式的目标足够紧密,并且受到@etoxin 的回答的启发,我们可以使命令更有用,如下所示:
Get-ChildItem | Rename-Item -NewName { $_.Name -replace '\.txt$','.log' }
也就是说,如果我们的正则表达式在管道之后充分过滤,则无需在管道之前进行过滤。并且在两个地方不再需要更改命令字符串(例如,如果您复制上述命令并且现在想使用它来更改“.xml”文件的扩展名)。
当您在所需的目录中时,这也很有效。
Dir | Rename-Item –NewName { $_.name –replace "old","new" }
现有的答案建议-replace
操作员,但如果文件被调用a.xml.xml
怎么办?两个.xml
子字符串都将被替换,最终结果将是a.tmp.tmp
. 幸运的是,有一个 .NET 方法可以做到这一点:
Dir *.xml | rename-item -newname { [io.path]::ChangeExtension($_.name, ".tmp") }
(Manish Kumar很接近,GetFileNameWithoutExtension
但这更优雅,可能更有效率,并不是说在这种情况下它过于重要)
这是另一个可行的变体。
dir *.xml | Rename-Item -NewName {$_.BaseName + ".tmp"}
$_.BaseName
将使用没有(最后一个)扩展名的“基本”名称。
使用别名的缩短版本将是:
ls *.xml | ren -new {$_.BaseName + ".tmp"}
dir -Recurse | where-object -FilterScript {$_.Extension -eq ".xml"} | Rename-Item -NewName {[System.IO.Path]::GetFileNameWithoutExtension($_.fullname) + ".tmp"}
使用 -WhatIf 先评估结果
更容易——记住替换搜索字符串是一个正则表达式,
dir *.xml | rename-item -newname {$_.name -replace "xml$","tmp"}
"$" 代表字符串的结尾,因此字符 "xml" 必须是文件名的最后三个字符。
这似乎可行,并且是一个pythonic,即简单胜于复杂(https://www.python.org/dev/peps/pep-0020/)的方式(一旦您在目录中):
$files = Get-ChildItem -file -Filter *.xml;
ForEach ($file in $files)
{
$n = $file.Basename
Copy-Item -Path $file -Destination "$n.tmp"
Remove-Item "$n.xml"
}