2017-03-08 212 views
0

我有一些PowerShell代码,旨在递归地从文件名中取出特定字符。这非常有效,除非将字符取出导致2个文件与相同文件夹中的名称匹配。Powershell递归重命名文件,而不是重命名重复

我在这里找到了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)等,具体取决于有多少。

请不要只给我一个答案,解释它,这样我可以了解正在发生什么

回答

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 
} 

- 在将数字添加到字符串以进行重复时分别处理扩展的另一个更新。我遇到的问题是,数字会在扩展名后加上文件名,这显然是不可行

+0

假设我在名为d $#ata.csv的文件夹中有三个文件,da $#ta.csv和dat $#a.csv - 您的代码如何处理? –

+0

@DaveSexton你是完全正确的。我已经修复了我相信我的更新,请看看其他问题吗? – GrumpyCrouton

+0

现在看起来不错。只是一般性评论,我认为你需要更多地了解Powershell的精神。在Powershell中,您拥有所有这些很酷的功能,如管道,范围和字符串扩展。你不需要那么复杂的字符串连接。例如你的输出行可以这样完成:''Rename''“$($ _。name)\'”为''New \''“''或其他替代方式如下:''Rename'{0 }“改为”{1}“'-f $ _。name,$ New'。 –

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} 

关于这样做的好处是,它可以在两个,三个或更多的重复值

我只是做了该代码的文件,所以你会需要另一个版本的文件夹。

+0

谢谢,但这看起来更复杂,然后它需要我。我不确定它是如何工作的 – GrumpyCrouton

+0

我认为理解它在做什么的方法是运行它并研究输出。首先从“开始”到“Group-Object”之前的管道运行它,然后从头开始运行它,但包括“Group-object”。代码将问题分解成步骤,每步成为管道连锁,链条。想想这样的步骤1)获取文件列表2)删除文件夹3)捕获文件路径和新文件路径4)在新文件路径上分组并重复计数5)通过组循环并添加计数如果需要6)重命名文件。听起来很简单。 –

+0

非常好的方法戴夫,我看到一个问题与以前的运行不会包含在组中的重复。 – LotPings