Powershell - rename item in sub folders

Viewed 147

I am new using powershell and I need some help with a script.

I been using dir | Rename-Item -NewName {$_.Name -replace "Abc_123", "XYZ"} to change a bulk of file names in a folder but I would like to do more. I need to change from "Alex_Chris_123_456_ABC" to "AC_123_456_ABC".

I imagine that it goes like this.

Get-ChildItem -File -Recurse | % { Rename-Item -Path $_.PSPath -NewName $_.Name.replace("Abc_123", "XYZ")}

But this only changes specific characters. How can I add a conditional statement that will get the 1st character of strings before the first integer?

1 Answers

You're not far off. With Rename-Item, you don't need a ForEach-Object loop in this case, because the NewName parameter can also take a scriptblock to perform an action on every file sent through the pipeline.

Try

$sourcePath = 'D:\Test'  # change this to the rootfolder where the files and subfolders are
Get-ChildItem -Path $sourcePath -File -Recurse | 
    Where-Object { $_.Name -match '^(\D+)(_.*)' } |  # see regex details below
    Rename-Item -NewName {
        # split on the underscore and join the first characters of each part together
        $prefix = ($matches[1].Split("_") | ForEach-Object { $_.Substring(0,1) }) -join ''
        '{0}{1}' -f $prefix, $matches[2]
    }

Regex details:

^             Assert position at the beginning of the string
(             Match the regular expression below and capture its match into backreference number 1
   \D         Match a single character that is not a digit 0..9
      +       Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)            
(             Match the regular expression below and capture its match into backreference number 2
   _          Match the character “_” literally
   .          Match any single character that is not a line break character
      *       Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
)
Related