Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I recursively rename folders with Powershell?

Recursive renaming files using PS is trivial (variation on example from Mike Ormond's blog):

dir *_t*.gif -recurse 
    | foreach { move-item -literal $_ $_.Name.Replace("_thumb[1]", "")}

I'm trying to recursively rename a folder structure.

The use case is I'd like to be able to rename a whole VS.NET Solution (e.g. from Foo.Bar to Bar.Foo). To do this there are several steps:

  1. Rename folders (e.g. \Foo.Bar\Foo.Bar.Model => \Bar.Foo\Bar.Foo.Model)
  2. Rename files (e.g. Foo.Bar.Model.csproj => Bar.Foo.Model.csproj)
  3. Find and Replace within files to correct for namespace changes (e.g. 'namespace Foo.Bar' => 'namespace Bar.Foo')

I'm currently working the first step in this process.

I found this posting, which talks about the challenges, and claims a solution but doesn't talk about what that solution is.

I keep running into the recursion wall. If I let PS deal with the recursion using a flag, the parent folder gets renamed before the children, and the script throws an error. If I try to implement the recursion myself, my head get's all achy and things go horribly wrong - for the life of me I cannot get things to start their renames at the tail of the recursion tree.

like image 990
rbellamy Avatar asked Jun 02 '11 15:06

rbellamy


People also ask

How do I rename multiple folders in PowerShell?

In Windows PowerShell, go to a file folder, enter dir | rename-item -NewName {$_.name -replace “My”,”Our”} and press Enter.

How do I rename multiple folders at once?

You can press and hold the Ctrl key and then click each file to rename. Or you can choose the first file, press and hold the Shift key, and then click the last file to select a group.

How do I change a directory name in PowerShell?

Rename-Item cmdlet is used to rename a folder by passing the path of the folder to be renamed and target name.

Can you mass rename folders?

Select multiple files in a folder. To do so, press and hold down the CTRL key while you are clicking files. After you select the files, press F2. Type the new name, and then press ENTER.


1 Answers

Here's the solution rbellamy ended up with:

Get-ChildItem $Path -Recurse | %{$_.FullName} |
Sort-Object -Property Length -Descending |
% {
    Write-Host $_
    $Item = Get-Item $_
    $PathRoot = $Item.FullName | Split-Path
    $OldName = $Item.FullName | Split-Path -Leaf
    $NewName = $OldName -replace $OldText, $NewText
    $NewPath = $PathRoot | Join-Path -ChildPath $NewName
    if (!$Item.PSIsContainer -and $Extension -contains $Item.Extension) {
        (Get-Content $Item) | % {
            #Write-Host $_
            $_ -replace $OldText, $NewText
        } | Set-Content $Item
    }
    if ($OldName.Contains($OldText)) {
        Rename-Item -Path $Item.FullName -NewName $NewPath
    }
}
like image 137
outis Avatar answered Oct 27 '22 05:10

outis