Tuesday, December 05, 2006

Unix Hack Of The Day: Hex to Decimal filenames

Today I needed to convert a bunch of file names with hex values in them into files names with decimal values in them. And here's how I did it.

First, to do the actual math, I used bc - the standard Unix command line calculator. bc does all sorts of neat things, and among them, display values in a different base than they are input in. You can do the following in bc:

bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
ibase=16
1
1  ; response
2
2  ; response
A
10 ; response
10
16 ; response

Next, to pick apart the name of the file so that I could rebuild them with a different filename, I used sed. I did something like:

prefix=`echo blah_AD.txt | sed 's/^\(.*\)_.*/\1//'`

This says to replace the entire string with the text leading up to the first _. The result here would be blah.

Finally, I wanted to take the converted decimal numbers and pad them with zeros. I did this by making use of the printf command. This looks like:

 # printf "@@ %04d @@" 32
 @@ 0032 @@

To put it all together, if I had a directory files like:

 something_1.txt
 something_a3.txt
 something_b9.txt
 something_cc.txt

And I wanted to end up with:

 something_0001.txt
 something_0163.txt
 something_0185.txt
 something_0204.txt

I would do

 ls *.txt | while read filename; \ 
   do prefix=`echo $filename | \ 
   sed 's/\(.*\)_.*[.]txt/\1/'` ; \ 
   hex=`echo $filename | sed 's/^.*_\(.*\)[.]txt/\1/ | tr a-z A-Z` ; \ 
   dec=`echo "ibase=16 ; $hex" | bc` ; \ 
   mv -v $filename `printf "%s.%04d.txt" $prefix $dec` ; \ 
  done

Simple, eh? Maybe not. But with practice, you can be cranking out commands like the ones above without even thinking about it.

No comments:

Post a Comment