Zero Padding Filenames

By: Cam Wohlfeil
Published: 2018-09-19 1100 EDT
Category: Solutions
Tags: bash, python

I always hate when filename ordering gets screwed up because numbers aren't handled properly (1.txt, 10.txt, 2.txt, etc.), so the easy solution is to zero-pad the numbers. Renaming a bunch of files to add some zeros is no fun though, so here's some solutions.

On Ubuntu, there's a handy utility named rename with lots of features for renaming lots of objects. rename 's/\d+/sprintf("%02d", $&)/e' *.txt will search and replace the first number-string it finds with a zero-padded version and leave the rest of the filename alone. The key here is "%02d", which will set it to use 2 digits (i.e. 01, 02) and *.txt, which will set it to only affect files with .txt extension.

Within bash there's many options, but my favorite is this oneliner:

for f in *.txt ; do if [[ $f =~ [0-9]+\. ]] ; then  mv $f `printf "%.5d" "${f%.*}"`.txt  ; fi ; done

Of course, in Python there's this short script:

import os
path = '/path/to/files/'
for filename in os.listdir(path):
    prefix, num = filename[:-4].split('_')
    num = num.zfill(2) # This is where the zero fill is done
    new_filename = num + + ".txt" # File name is built here, may require editing
    os.rename(os.path.join(path, filename), os.path.join(path, new_filename))

The Python solution can be easily modified for directories instead:

import os
path = '/path/to/files/'
for fn in os.listdir(path):
    if not os.path.isdir(os.path.join(basedir, fn))
        continue
    else:
        prefix, num = fn[:-4].split('_')
        num = num.zfill(4)
        new_fn = num + ".txt"
        os.rename(os.path.join(path, filename), os.path.join(path, new_filename))

References