我目前有一行批量重命名我目前所在文件夹中的文件。
dir | foreach { move-item -literal $_ $_.name.replace(".mkv.mp4",".mp4") }
此代码适用于我当前所在的目录,但我想要的是从包含11个子文件夹的父文件夹运行脚本。我可以通过单独导航到每个文件夹来完成我的任务,但我宁愿运行一次脚本并完成它。
我尝试了以下内容:
get-childitem -recurse | foreach { move-item -literal $_ $_.name.replace(".mkv.mp4",".mp4") }
有谁能请我指出正确的方向吗?我根本不熟悉Powershell,但在这种情况下它符合我的需要。
答案 0 :(得分:32)
有一个鲜为人知的功能是专为这种情况而设计的。简而言之,您可以执行以下操作:
Get-ChildItem -Recurse -Include *.ps1 | Rename-Item -NewName { $_.Name.replace(".ps1",".ps1.bak") }
这可以通过传递参数NewName的scriptblock来避免使用ForEach-Object。 PowerShell足够聪明,可以为每个被管道对象评估scriptblock,设置$ _就像使用ForEach-Object一样。
答案 1 :(得分:25)
你很亲密:
Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace(".mkv.mp4",".mp4")}
答案 2 :(得分:0)
请注意,如果您仍然遇到Cannot rename because item at '...' does not exist.
之类的错误,您可能正在处理某些超长路径和/或带有“特殊解释”字符的路径,例如方括号(即[
]
)。
在这种情况下,请将-LiteralPath
/ -PSPath
与特殊前缀\\?\
(对于UNC路径,您将要使用前缀\\?\UNC\
)一起使用,直至32k个字符。我还建议尽早过滤(使用Get-ChildItem
)以提高性能(较少的Rename-Item
调用会更好)。
$path = 'C:\Users\Richard\Downloads\[Long Path] THE PATH TO HAPPINESS (NOT CLICKBAIT)\...etc., etc.'
# -s is an alias for -Recurse
# -File for files only
# gci, dir, and ls are all aliases for Get-ChildItem
# Note that among the 3, only `gci` is ReadOnly.
gci -s -PSPath $path -File -Filter "*.mkv.mp4" |
# ren, rni are both aliases for Rename-Item
# Note that among the 2, only `rni` is ReadOnly.
# -wi is for -WhatIf (a dry run basically). Remove this to actually do stuff.
# I used -replace for regex (for excluding those super rare cases)
rni -wi -PSPath { "\\?\$($_.FullName)" } -NewName { $_.Name -replace '\.mkv(?=\.mp4$)','' }