Powershell以递归方式重命名文件,而不是重命名重复文件

时间:2017-03-08 16:40:35

标签: powershell recursion

我有一些powershell代码,用于递归地从文件名中取出特定字符。这很好用,除非取出字符导致2个文件匹配同一文件夹中的名称。

我在这里找到了Powershell PowerShell script to remove characters from files and folders,但它没有解决我遇到的问题。

$characters = "$#"
$regex = "[$([regex]::Escape($characters))]"

$filesandfolders = Get-ChildItem -recurse "D:\projects\filenameCleaner\TEST" | Where-Object {$_.name -match $regex} 
$filesandfolders | Where-Object {!$_.PsIscontainer}  |  foreach {
    $New=$_.name -Replace $regex
    Rename-Item -path $_.Fullname -newname $New -passthru
}
$filesandfolders | Where-Object {$_.PsIscontainer}  |  foreach {
    $New=$_.name -Replace $regex
    Rename-Item -path $_.Fullname -newname $New -passthru
}

我对Powershell还不是很精通,并希望得到一些帮助。我只想要一个脚本,如果找到重复的话,它应该只在末尾添加一个(1)或(2)等,具体取决于有多少。

请不要只给我一个答案,解释一下,这样我才能了解正在发生的事情

2 个答案:

答案 0 :(得分:3)

我认为解决这个问题的方法是创建一个包含源路径和目标路径的新PSOBJECT。然后,您可以使用Group-object在目标路径上进行分组,这将为您提供一个计数,然后您可以使用该计数来确定哪些文件需要数字后缀。

这样的事情:

Get-ChildItem -recurse "D:\projects\filenameCleaner\TEST" | ? {!$_.PsIscontainer} | % {
    New-Object psobject -Property @{
        source = $_.FullName
        target = ($_.FullName -replace [regex]::Escape($_.Name)) + ($_.Name -replace '[\$#]+', '') 
    }
} | Group-Object target | % {
    $g = $_.Group
    0..($g.Count - 1) | % {
        New-Object psobject -Property @{
            source = $g[$_].source
            target = $g[$_].target -replace '\.',  @('.', "($($_)).")[$_ -gt 0]
        }        
    }
} | % {Rename-Item -Path $_.source -NewName $_.Target}

这样做的好处是它可以有两个,三个或更多个重复项

我只完成了文件代码,因此您需要另一个文件夹版本。

答案 1 :(得分:0)

我能够通过添加检查新路径的if语句来实现这一点

$characters = "$#}"
$regex = "[$([regex]::Escape($characters))]"
$path = "D:\projects\filenameCleaner\TEST"
$filesandfolders = Get-ChildItem -recurse $path | Where-Object {$_.name -match $regex} 
$filesandfolders | Where-Object {!$_.PsIscontainer}  |  foreach {
    $New=$_.name -Replace $regex
    $newPath = $path+"\"+$New
    $loop = 0
    while (Test-Path $newPath) {
        $loop = $loop + 1
        $basename = $_.basename -Replace $regex
        $New = $basename + " ("+$loop+")"+$_.extension
        $newPath = $path+"\"+$New
    }
    "Rename `""+$_.name+"`" to `""+$New+"`""
    Rename-Item -path $_.Fullname -newname $New -passthru
}
$filesandfolders | Where-Object {$_.PsIscontainer}  |  foreach {
    $New=$_.name -Replace $regex
    $newPath = $path+"\"+$New
    $loop = 0
    while (Test-Path $newPath) {
        $loop = $loop + 1
        $basename = $_.basename -Replace $regex
        $New = $basename + " ("+$loop+")"+$_.extension
        $newPath = $path+"\"+$New
    }
    "Rename `""+$_.name+"`" to `""+$New+"`""
    Rename-Item -path $_.Fullname -newname $New -passthru
}

- 在将字符串添加到字符串中时,另一个更新处理扩展名。我遇到的问题是,在扩展后这个号码会进入文件名,这显然是一个禁忌