Zero padding filenames using bash in Linux

September 2nd, 2010 | Categories: Linux, programming | Tags:

I recently had a set of files that were named as follows

frame1.png
frame2.png
frame3.png
frame4.png
frame5.png
frame6.png
frame7.png
frame8.png
frame9.png
frame10.png


and so on, right up to frame750.png. The plan was to turn these .png files into an uncompressed movie using mencoder via the following command (original source)

mencoder mf://*.png -mf w=720:h=720:fps=25:type=png -ovc raw -oac copy -o output.avi


but I ended up with a movie that jumped all over the place since the frames were in an odd order. In the following order in fact

frame0.csv
frame100.csv
frame101.csv
frame102.csv
frame103.csv
frame104.csv
frame105.csv
frame106.csv
frame107.csv
frame108.csv
frame109.csv
frame10.csv
frame110.csv


This is because globbing expansion (the *.png bit) is alphabetical in bash rather than numerical.

One way to get the frames in the order that I want is to zero-pad them. 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


You may want to change the number of digits used in each filename from 3 to 5 (say). To do this just change %03d in zeropad.sh to %05d

Let me know if you find this useful or have an alternative solution you’d like to share (in another language maybe?)

1. I tend to use rename, though it never seems elegant (apologies if my rename syntax is goofy). Something like:
rename ‘s/file/file0/’ file?.png
rename ‘s/file/file0/’ file??.png

2. Write a Perl script. You can sort based on natural numerical order, rather than strict alphabetical order.

3. ls *.tif | sort -n will give you them in numerical order. You can also put it between tacks “ and that way use it as an argument somewhere.

4. Sorry about the *.tif bit. Any extension of course.