PowerShell批量重命名文件时避免名称冲突的极简实现
解决PowerShell批量重命名时的文件名冲突问题
下面是修改后的代码,在尽量保留原逻辑的基础上,增加了文件名冲突检查,自动递增序号直到找到未被使用的名称:
# 处理MP4文件 Get-ChildItem "$env:Userprofile\Videos\Movie_Best_Clips" -Filter "vlc-record-2024*.mp4" -Recurse | ForEach-Object { $dirName = $_.Directory.Name $ext = $_.Extension $i = 0 do { $newName = "{0}_{1:D4}{2}" -f $dirName, $i, $ext $newPath = Join-Path $_.Directory.FullName $newName $i++ } while (Test-Path $newPath) Rename-Item $_.FullName -NewName $newName } # 处理MKV文件 Get-ChildItem "$env:Userprofile\Videos\Movie_Best_Clips" -Filter "vlc-record-2024*.mkv" -Recurse | ForEach-Object { $dirName = $_.Directory.Name $ext = $_.Extension $i = 0 do { $newName = "{0}_{1:D4}{2}" -f $dirName, $i, $ext $newPath = Join-Path $_.Directory.FullName $newName $i++ } while (Test-Path $newPath) Rename-Item $_.FullName -NewName $newName }
关键改动说明
- 把全局的
$i移到每个文件的处理逻辑内,确保每个文件从0开始尝试序号,避免跨目录的序号混乱 - 使用
do-while循环结合Test-Path检查目标文件是否存在:如果存在就递增序号,直到生成的文件名在当前目录中不存在 - 用
Join-Path拼接完整路径,确保检查的是当前文件所在目录下的文件名冲突,而不是其他目录 - 提取文件扩展名到变量
$ext,让代码更简洁,也方便后续扩展其他格式
如果想进一步精简代码,可以把冲突检查逻辑封装成一个小函数,避免重复代码:
function Get-AvailableFileName { param( [string]$Directory, [string]$BaseName, [string]$Extension ) $i = 0 do { $newName = "{0}_{1:D4}{2}" -f $BaseName, $i, $Extension $newPath = Join-Path $Directory $newName $i++ } while (Test-Path $newPath) return $newName } # 统一处理MP4和MKV文件 Get-ChildItem "$env:Userprofile\Videos\Movie_Best_Clips" -Include "vlc-record-2024*.mp4", "vlc-record-2024*.mkv" -Recurse | ForEach-Object { $newName = Get-AvailableFileName -Directory $_.Directory.FullName -BaseName $_.Directory.Name -Extension $_.Extension Rename-Item $_.FullName -NewName $newName }
这个精简版本用-Include参数一次性筛选两种格式的文件,通过函数复用冲突检查逻辑,代码更整洁,同时保留了原需求的核心功能。
内容的提问来源于stack exchange,提问作者Vicky Dev
相关产品推荐
相关产品推荐

