2017-03-08 210 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