Thursday, May 14, 2009

Batch file renaming

Batch file renaming can be pretty handy as it saves loads of time when you have to rename thousands of files. There are many simple ways to do it though.

If you have files with same ending pattern it can be done as:

e.g. if you want all .htm to be renamed to .html

rename .htm .html *.htm


and On other Unixes, we'd have to do something like this to batch rename files:


for i in *.html
do
j=`echo $i | sed 's/.htm$/.html/'`
# or, in this simple case even just: j=$"i"l
mv $i $j
done


Though if we had bash or ksh, we could make that a little less cumbersome:


for i in *.htm
do
j=${i%.htm}.html
# or: j=${i}l
mv $i $j
done


The Linux "rename" isn't going to handle to more complex cases though. For example, I had to transfer mail files from one system to another recently. On the old system, each message would be named something like "1124993500.7359464636.e-smith". On the new system, they'd be "00000001.eml", with hexadecimal numbering going on up, so you'd get "00000009.eml" and the next message would be "0000000a.eml", and so on. There's no way for "rename" to do that, but a loop can:


for i in *
do
j=`printf "%0.9x.eml\n" $x`
mv $i $j
x=$((x+1))
done


And if you dont want to follow any pattern and simply add new extension to all the files in a directory:

for i in $(ls -lArt /path/to/directory |awk '{print $9}');do mv $i $i.txt; done


adding to it if files are placed recursively in directories:

for i in $(find /path/to/root -type f -print);do mv $i $i.txt; done

No comments:

Post a Comment