2

I'm new to using PowerShell and am wondering how to simply pad number strings contained in several similar file names to have the same number of digits in each file name.

That is, I have a folder containing these 300 files:

dummy name 1.txt through dummy name 300.txt

and would simply like rename the files that have less than 3 digits in them to all have exactly 3 digits, such as:

dummy name 001.txt through dummy name 300.txt

Laurence
  • 721
  • 7
  • 24
D. Whittaker
  • 31
  • 1
  • 3
  • 3
    `gci | ren -n {[regex]::replace($_.basename, '\d+', {"$args".PadLeft(3, '0')})}` – TessellatingHeckler Sep 16 '17 at 01:46
  • I tried this at first (which didn't work obviously): $i = 1 Get-ChildItem *.txt | %{Rename-Item $_ -NewName ('{0:D3}.txt' -f $i++)} – D. Whittaker Sep 16 '17 at 02:02
  • This is a tempting dupe target https://stackoverflow.com/questions/18304025/bulk-renaming-of-files-in-powershell-with-sequential-numeric-suffixes/18305871#18305871 – Matt Sep 16 '17 at 02:03
  • Thanks for the response. It worked on the file name but it deleted the file extension. Do you know how to keep the file extension unchanged? – D. Whittaker Sep 16 '17 at 02:04
  • 1
    Oh so it did; whoops. Try `$_.Name` instead of `$_.BaseName` – TessellatingHeckler Sep 16 '17 at 02:59
  • @TessellatingHeckler - can you help me with this? I am using a solution very similar to what you proposed here (thanks!), but I don't understand why the PadRight component isn't working: https://stackoverflow.com/q/68960214/9964553 – LBro Aug 27 '21 at 23:36

5 Answers5

2

If your files were produced sequentially and you've got name1.txt , name2.txt, etc.,

And you want name0001.txt, name0002.txt, etc.

You can do

$j=1;

foreach ($i in Get-ChildItem "./name?.txt" -Name) {
    echo $i;
    $new_name = "name000" + $j + ".txt";
    Rename-Item -Path $i -NewName $new_name;
    $j=$j+1;
}

... Then do it again, changing $j to 10 at the start, taking a 0 off, and so on for the hundreds.

Okay for a one off and if you can then fix what's producing the files in the first place.

David Buck
  • 3,752
  • 35
  • 31
  • 35
2

@TessellatingHeckler gave good answer in the comments:

gci | ren -n {[regex]::replace($_.name, '\d+', {"$args".PadLeft(3, '0')})}
alexkovelsky
  • 3,880
  • 1
  • 27
  • 21
1

I would do it like this:

$i=0;
$nameLike='dummy name'
[int]$currentid=0
#RENAME TO REMOVE THE SPACE IN THE MIDDLE
gci -File -Path "./" | where{ $_.name -like "$nameLike*"} | %{
    #remove space in the middle
    $newname = $_.Name.Split(' ')[0] + $_.Name.Split(' ')[1]

    #convert the name into the padding you want (3)
    [int]::TryParse($_.Name.Split(' ')[2].Split('.')[0],[ref]$CurrentId) | Out-Null
    $newname = $newname + $CurrentId.ToString("000") + $_.Extension
    Rename-Item -Path $_.FullName -NewName $newname
}

Details in here: https://medium.com/@josegabrielortegac/powershell-renaming-files-with-powershell-e9012573647a?sk=502148e039058d84fe34608d77cd1aa2

Jose Ortega
  • 1,002
  • 13
  • 23
0

Try this:

1..300 | %{
     $source = "dummy name $_.txt"
     $target = ('dummy name {0:00#}.txt' -f $_)
     rename-item  $source -NewName $target
     }

Notes:

  1. The outer loop is a little unconventional. Most scripters code this to resemble a java for loop.

  2. The choice of single and double quotes is intentional. Be careful.

  3. The code is a little inelegant, because some parts of the filename are typed in twice.

  4. The assumption is that all 300 files exist. If not, you will get errors.

Walter Mitty
  • 18,205
  • 2
  • 28
  • 58
-1

try this:

Get-ChildItem "c:\temp\" -file -Filter "*.txt" | where basename -match ". \d{1,2}$" | %{
$res=$_.BaseName -split '(.)(\d{1,2})$'
$newnamme="{0}\{1} {2:D3}{3}" -f $_.Directory, $res[0], [int]$res[2], $_.Extension
Rename-Item $_.FullName $newnamme
}
Esperento57
  • 16,521
  • 3
  • 39
  • 45