Home > Software design >  Powershell Script to clean up file names
Powershell Script to clean up file names

Time:08-18

I have a script that I use to clean up file names to match my preffered style/format. It works as is, but its kinda ugly and does a loop for each change. Ideally it would process all the changes for each file name at once and then proceed to the next, rather then grabbing the gci every time.

Any suggestions on making this a bit more elegant/streamlined? Thanks!

#need this for camel casing later
$Culture = Get-Culture
#Remove Other Tags
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('(retail)','') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('(epub)','') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('(mobi)','') }
#Pad Dashes
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('-',' - ') }
#Replace Underscores with Spaces
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('_',' ') }
#Replace dots with space except for in the extension
Get-ChildItem -Recurse | Rename-Item -NewName { ($_.BaseName -replace '\.',' ')   $_.Extension }
#Rename to Camel Casecd 
Get-ChildItem -recurse | Rename-Item -NewName {$Culture.textinfo.totitlecase($_.FullName)}
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace(' .','.') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('.Epub','.epub') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('.Pdf','.pdf') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('.Mp3','.mp3') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('For','for') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('And','and') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('In','in') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('On','on') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('Of','of') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('From','from') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('To','to') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace(' A ',' a ') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace(' i',' I') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('epubo O','epub') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('Html','HTML') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('Css','CSS') }
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('Css','CSS') }
#Remove Double Spaces 
Get-ChildItem -Recurse | Rename-Item -NewName { $_.Name.Replace('  ',' ') }

CodePudding user response:

Here is a proposal if you think it is elegant :

$hash = @{'(retail)' = ''; '(epub)' = ''; '(mobi)' = ''; 'And' = 'and' } #To be completed
    
$Culture = Get-Culture
$items = Get-ChildItem -Recurse
foreach ($item in $items) {
    $name = $item.Name
    foreach ($h in $hash.Keys) {
        $name = $name.Replace($h, $hash.$h)
    } 
    Rename-Item -Path $item.FullName -NewName $name
}

CodePudding user response:

I know it is probably not complete but it might be an inspiration for further improvements ;-)

Get-ChildItem -Recurse | 
ForEach-Object {
    $NewBaseName = $_.BaseName -replace '\(epub\)' -replace '\(mobi\)' -replace '\(retail\)'
    $NewBaseName = $NewBaseName -replace '-', ' - ' -replace '_', ' ' -replace '\.', ' ' -replace '\s ', ' '
    $NewBaseName = $NewBaseName.toLower() -replace 'epubo O', 'epub' -creplace 'html', 'HTML' -creplace 'css', 'CSS'
    $NewExtension = $_.Extension.toLower()
    $NewName = Join-Path -Path $_.Directory -ChildPath ($NewBaseName   $NewExtension)
    Rename-Item -Path $_.FullName -NewName $NewName
}

This way you traverse the directories only once. That should at least be faster than your approach.

  • Related