Zero padding filenames using bash in Linux
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?)
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
Write a Perl script. You can sort based on natural numerical order, rather than strict alphabetical order.
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.
Sorry about the *.tif bit. Any extension of course.