5Sep2007

Ever want to change the file extension for a group of files in one fell swoop? Me too. If you are using a unix-like system (Linux, Solaris, OS X, etc) then this is extremely easy using a Bash script. If you are on a Windows system then stop everything right now and go install the Cygwin environment.

The task at hand is actually pretty easy and can be done as a one liner, but I thought I’d create a more general purpose script. That way I can just use my script the next time I need to rename some files.

OLDEXT=${2/#.}
NEWEXT=${3/#.}

find "${1}" -iname "*.${OLDEXT}" |
while read F
do
  NEWFILE="${F/%${OLDEXT}/${NEWEXT}}"
  echo "mv \"${F}\" \"${NEWFILE}\""
  mv -f "${F}" "${NEWFILE}"
done

The numbers 1, 2 and 3 represent command-line arguments. You’ll see above the first thing I do is store the 2nd argument as the old extension and strip off any leading “dot”. I do the same with the 3rd argument storing it as the new extension. Next I do a find with the first argument being the search directory. Notice the iname option which means it will do a case insensitive name match. I pipe the results of the find into a while loop, calculate the new filename and rename/move the file. That’s it! Below is the full script file which includes a usage statement and some pretty comments.

Note: if the file here doesn’t work for you then you may simply need to retype it. I created the file on a Cygwin environment in Windows and sometimes when you move files from Windows over to a Unix system there are special characters which prevent it from being executed.



3 Comments

1

Thanks for that, Jonathan

Is there a simple way to adapt the script to accept multiple incoming extensions all at once (say, psd, tif, jpg)

I’m tying it in with some “sips” usgae on OS X to batch convert entire directory trees to small jpegs.

Thanks, Ben



Bash is very powerful and you can basically tell it to do whatever you want… so sure!

You could try playing with the find syntax. I was able to get find to get a listing of files with it’s -iregex option, which uses regular expressions to find the files.

find "${1}" -regextype "posix-extended" -iregex ".*.(psd|tif|jpg)"

You could hard code the extensions in your find statement or you could pass them in on the command line if you liked.


3

Thanks Jonathan, you’ve saved my day.
I’ve adapted your script to ’svn mv’ files by changing extension.
Honestly, I didn’t know the /# /% syntax inside brackets!


 




Leave a comment