2
votes

I have .mp3 files in my folder with these names: 2.mp3,4.mp3,6.mp3,8.mp3,10.mp3,12.mp3,...102.mp3,104.mp3... and would like to rename them all and get following result: 0001.mp3,0002.mp3,0003.mp3,0004.mp3...

the following code changes the names of all files, but the problem is that it does not change/sort them in the exact original order as they are originally displayed in my folder.

$i = 1
Get-ChildItem *.mp3 | %{Rename-Item $_ -NewName ('{0:D4}.mp3' -f $i++)}

Something like this written below I want to achieve

  • 2.mp3 -> 0001.mp3
  • 4.mp3 -> 0002.mp3
  • 6.mp3 -> 0003.mp3
  • 8.mp3 -> 0004.mp3
  • 10.mp3 -> 0005.mp3
  • 12.mp3 -> 0006.mp3
  • ...

I have currently come to this half-solution that does not work and I do not know how to proceed/solve this problem.

$i = 1
Get-ChildItem *.mp3 | %{Rename-Item $_ -NewName {'{0:D4}.mp3' -f [int]($_.BaseName -replace '\D') $i++ }}
1
"I have currently come to this half-solution that does not work" - what's wrong with it?Mathias R. Jessen
Just remove $i++ from your half-solution and it should work.zett42
you can save the G-CI call to an array and then use the index number plus 1 to derive the number.Lee_Dailey

1 Answers

0
votes

Use Sort-Object to sort them according to the numerical value in the name before you start renaming:

$i = 1
Get-ChildItem *.mp3 |Sort-Object {[int]($_.BaseName -replace '\D')} | Rename-Item ...

Although you may run into unexpected errors because $i++ does not have the effect you intend - the ++ operation creates a new local copy of $i without ever incrementing $i in the parent scope.

We can solve that by explicitly passing a reference to $i:

$i = 1
Get-ChildItem *.mp3 |Sort-Object {[int]($_.BaseName -replace '\D')} | Rename-Item -NewName {'{0:D4}.mp3' -f ([ref]$i).Value++}