Home > Back-end >  How to change the current folder name in Powershell
How to change the current folder name in Powershell

Time:10-22

How can I change the current folder name in Powershell? After cutting the basename I want to rename the current basename with $NewName2. But all tries don't work. Are there any hints for me for the correct Rename-Item syntax.

Example:

current Basename: Ultralongfoldernametochange

after cutting:
$NewName2: Ultralongf

$AllDir = Get-ChildItem -LiteralPath E:\ -Recurse -Directory | Where-Object { $_.FullName.Length -ge 95 }

foreach($file in $AllDir)
{

 if ($file.Basename.Length -ge 44) 
    {
    $NewName2 = ($file.BaseName[0..9] -join '')
    Rename-Item ???
    }
}

CodePudding user response:

You need to define both old name with full path and new name without full path.

You should consider using the SubString method rather retrieving an array and joining it : $file.BaseName.Substring(0, 10) will retrieve the 10 first characters (0 is the position of the first character, 10 to get 10 characters - and not the 10th position).

Get-ChildItem -LiteralPath E:\ -Directory -Recurse| ForEach-Object {
   If ($_.BaseName.Length -ge 44)
   {
       $i = 10
       While ((Test-Path "$($_.PSParentPath.SubString(38))\$($_.BaseName.SubString(0, $i))")
          -and $i -lt $_.BaseName.Length)
       {
           $i  
       }
       Rename-Item $_.FullName $_.BaseName.SubString(0, $i)
   }
}

PSParentPath property always start with the first 38 characters Microsoft.PowerShell.Core\FileSystem::, so they are remove (while this is not mandatory here, I used to do this - to storing values somewhere, ...). The While loop is to avoid errors if the new name we want to define already exists, if so we try with one more character, etc... until no name are matching.

$i -lt $_.BaseName.Length test is to avoid infinity loops.

If there is no match, only the 10 first characters will be used.

CodePudding user response:

You can streamline your command as follows, using a delay-bind script block with Rename-Item:

Get-ChildItem -LiteralPath E:\ -Recurse -Directory | 
  Where-Object { $_.FullName.Length -ge 95 -and $_.BaseName.Length -ge 44 } |
  Sort-Object -Descending { $_.FullName.Length } |
  Rename-Item -NewName { $_.BaseName.Substring(0, 10)   $_.Extension } -WhatIf

Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

Note:

  • As Theo notes, it is important to start with the longest paths first, so that directories renamed earlier do not interfere with attempts to rename later ones; the Sort-Object call ensures that.

  • There could be name collisions, which the above command doesn't try to handle.

  • While it is rare for directories to have extensions, the above command preserves them, if present, but note that it therefore adds to the length of the resulting new name.

  • $string.Substring(0, 10) is the faster equivalent of $string[0..9] -join '' (or, more succinctly, -join $string[0..9])

  • Related