Powershell Prefix every filename with the directory name it resides in

Just like the subject says, I need to rename every file in a folder by prefixing the directory name. I tried this but it seems to process each file over and over until an error occurs

gci | Where {$_.psIsContainer -eq $false} | Rename-Item -NewName {$_.Directory.Name + " " + $_.Name}

Ideally, I would like this to work recursively

TIA


Solution 1:

one problem with using Get-ChildItem and Rename-Item in a pipeline is that the G-CI call keeps grabbing files from the same dir ... and will often see the renamed file as a file that has not yet been fed into the pipeline.

that can end up with the same file being acted on multiple times. [grin]

the solution to that is to wrap the G-CI call in parens so that it grabs all the files at one time and then feeds them one-at-a-time to the pipeline.

also, you can use the -File parameter of G-CI to avoid the Where-Object filter you have in your code.

also also, you can use the -Recurse parameter of G-CI to go thru the whole dir tree.

that leads me to the following code.

yours ...

gci | Where {$_.psIsContainer -eq $false} | Rename-Item -NewName {$_.Directory.Name + " " + $_.Name}

my version of yours ...

(Get-ChildItem -File -Recurse) |
    Rename-Item -NewName {$_.Directory.Name + ' ' + $_.Name}

a few other changes that seem worthwhile to me ...

  • specify a path in the G-CI call
    i am wary of depending on what the OS or PoSh may consider the "current dir". [grin]
  • build the new file name with something that feels more robust to me
    i would pro'ly use the -f string format operator to build the string instead of the sometimes iffy + concatenation operator.