Batch rename sequential files by padding with zeroes

Python

import os
path="/path/to/files/"
for filename in os.listdir(path):
    prefix, num = filename[:-4].split('_')
    num = num.zfill(4)
    new_filename = prefix + "_" + num + ".png"
    os.rename(os.path.join(path, filename), os.path.join(path, new_filename))

you could compile a list of valid filenames assuming that all files that start with “output_” and end with “.png” are valid files:

l = [(x, "output" + x[7:-4].zfill(4) + ".png") for x in os.listdir(path) if x.startswith("output_") and x.endswith(".png")]

for oldname, newname in l:
    os.rename(os.path.join(path,oldname), os.path.join(path,newname))

Bash

(from: http://www.walkingrandomly.com/?p=2850)

In other words I replace file1.png with file001.png and file20.png with file020.png and so on. Here’s how to do that in bash

#!/bin/bash
num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'`
paddednum=`printf "%03d" $num`
echo ${1/$num/$paddednum}

Save the above to a file called zeropad.sh and then do the following command to make it executable

chmod +x ./zeropad.sh

You can then use the zeropad.sh script as follows

./zeropad.sh frame1.png

which will return the result

frame001.png

All that remains is to use this script to rename all of the .png files in the current directory such that they are zeropadded.

for i in *.png;do mv $i `./zeropad.sh $i`; done

Perl

(from: Zero pad rename e.g. Image (2).jpg -> Image (002).jpg)

use strict;
use warnings;
use File::Find;

sub pad_left {
   my $num = shift;

   if ($num < 10) {
      $num = "00$num";
   }
   elsif ($num < 100) {
      $num = "0$num";
   }

   return $num;
}

sub new_name {
   if (/\.jpg$/) {
      my $name = $File::Find::name;
      my $new_name;
      ($new_name = $name) =~ s/^(.+\/[\w ]+\()(\d+)\)/$1 . &pad_left($2) .')'/e;
      rename($name, $new_name);
      print "$name --> $new_name\n";
   }
}

chomp(my $localdir = `pwd`);# invoke the script in the parent-directory of the
                            # image-containing sub-directories

find(\&new_name, $localdir);

Rename

Also from above answer:

rename 's/\d+/sprintf("%04d",$&)/e' *.png

Leave a Comment