21

I would like to rename all the jpg files in a folder to uniform convention like Picture00000001.jpg where 00000001 is a counter.

It would be a walk in the park in C# but I would think this is the kind of bread and butter stuff that PowerShell was made for.

I'm guessing something like

$files = ls *.jpg
$i=0
foreach($f in $files) { Rename-Item $f -NewName "Picture"+($i++)+".jpg" }

But before I hit the gas on this I would like to 1) format the counter, and 2) have some sense that this is in fact even a good idea.

If this sounds more like OCD than a good idea please speak up.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ralph Shillington
  • 20,718
  • 23
  • 91
  • 154

2 Answers2

25

You can do this fairly simply in PowerShell:

ls *.jpg | Foreach -Begin {$i=1} `
   -Process {Rename-Item $_ -NewName ("Picture{0:00000000}.jpg" -f $i++) -whatif}

If you're looking for the "basename" and if you're on PowerShell 2.0 just use the Basename property that PowerShell adds to each FileInfo object:

ls *.jpg | Format-Table Basename

Note that on PowerShell 1.0, the PowerShell Community Extensions adds this same Basename property.

If the intent is to append a counter string to the file's basename during the rename operation then try this:

ls *.jpg | Foreach {$i=1} `
   {Rename-Item $_ -NewName ("$($_.Basename){0:00000000#}.jpg" -f $i++) -whatif}
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • Sorry for the disconnect between title and question -- I've changed the title. – Ralph Shillington Oct 06 '09 at 01:35
  • Whoa, you can give a `begin` and `process` script block individually to `ForEach-Object`? I have to revisit some golfed PE problems. – Joey Oct 06 '09 at 05:52
  • Hm, I just wonder *why* this works. The documentation says nothing about the `-Begin` and `-End` parameters to `ForEach-Object` being positional. Magic? – Joey Oct 06 '09 at 06:13
  • 1
    Yes, I was using the parameters -begin and -process implicitly so I updated one example to state this explicitly. Normally when you use Foreach, you are "positionally" using the -Process parameter for the scriptblock you provide. Not sure how the positional "magic" works in the Begin/End case but it is has been this way since the early days. – Keith Hill Oct 06 '09 at 15:16
  • 1
    Ah, I just was a little confused. It's clear what two (or three) scriptblocks do, but `help % -param begin` only tells me that "named" is the only possibility here. Neither are there examples or other documentation in `help %` for that case. That's why I was wondering. But nice to know that this works. – Joey Oct 06 '09 at 15:35
2

Try this to get the FilenameWithOutExtension

$f.DirectoryName + "\" + $f.BaseName
Ste
  • 1,729
  • 1
  • 17
  • 27
Brent
  • 118
  • 6