26th Jun 2005

Posted in

Blog :: And now for something completely different...

So, no newsflash here, but programmers love unix.  There are of course exceptions to the rule, but in general people I respect as programmers have a high degree of appreciation for the various flavors of desktop Unix (Linux, BSD, MAC OS X?) as productive programming environments.

One reason for this is the immense value of the command line for eliminating repetitive tasks. (Doesn't "repetitive" strike you as an onomatopoeic word?)  I am in the middle of creating image galleries for a friend's website.  I've got five or six folders full of images and find myself having to do repetitive tasks across multiple folders.  I won't bore you with my ability to resize 300 photos from the command line with a single command that specifies jpeg compression and maximum dimensions.  Instead I'll present you with the simpler problem I solved a moment ago.

The way the "files only, no db" version of my image gallery works, is by filename convention.  For instance I expect to find a file named "index" (ignoring extension) in a directory that represents an image gallery.  Index will not be displayed in the gallery layout and won't have a thumbnail generated but it will represent the gallery on the page that lists the different photo galleries.  Currently "index" has to be all lower case. I'll fix the case insensitivity later, but right now I'm trying to get the site up as fast as possible.  Stephanie has been helping me categorize the images and picked the Index for each gallery, but named it "Index".  So my problem is this: how do I rename to lower case half a dozen files in seperate directories?

If I was on windows, I'd navigate to each folder and manually rename the file.  If I had a hundred files on Windows I would write a script (python tho, not WSH VBScript).  On unix the shell hits the sweet spot for tasks that are irritating to do manually but too small or one-off to break out an editor and write a script to solve. I know I can use the find command to find all the files named "Index" so

find . -name Index.???

generates a listing like

./In_the_Studio/Index.JPG
./Memorial_Day_2005/Index.JPG
./Songfest_2000/Index.JPG
./Songfest_2001/Index.jpg
./Songfest_2002/Index.JPG
./Songfest_2003/Index.JPG
./Songfest_2004/Index.jpg

The find command, btw, takes a directory to work on (. in this case refers to the current directory I am executing the command in) and optionally a flag. I used the -name flag and supplied it with a filename pattern: I'm looking for files named Index with a 3 character extension.

Now I just need to rename those files. I was initially thinking of using the mv command by way of xargs. But just saying rename makes me think there should be a command named rename... And there is! A quick visit to a man page and I generate the following command

find . -name Index.??? | rename s/Index/index/
This command pipes the output of my find command to the rename command. Then on each filename it gets, rename runs the regular expression "s/Index/index/". The first "s" says replace the next part "Index" with the third part ("index"). One command and thirty seconds of thought... For those who can figure it out, Bash is a swiss-army-chainsaw of functionality.

Posted on Jun 26th 2005, 12:38 PM