//View Tip #27
Similar Tips
» Random IP addresses
» Count files by type
» Counts files in the current directory and subdirectory
» Kill matching processes without unnecessary greps and extra sh p
» Concatenate pairs of lines


Latest tips by RSS
Click here to subscribe
Follow Shell-Fu on Twitter
Click here to follow
Follow Shell-Fu on identi.ca
Click here to follow
Use awk to change the file extension for a group of files. For example to change all .htm files to .php:

ls *htm | awk -F. '{print "mv "$0" "$1".php"}' | sh

This can be tested first by leaving the '| sh' off to give a list of the commands that will be executed.

View Comments »


Add your comment

Comments are currently disabled
this is so wrong...

first of all you NEVER pipe the output of ls, it's unsafe and totally unnecesary all the time, in this particular case you can just pass *htm to awk itself.

second this won't work with filenames that contain spaces, or newlines (which are valid).

another useless advice is to print the commands and feed them to sh! this can be done FAR better with shell constructs alone, like:

 for filename in *htm; do
     mv "$filename" "${filename}".php

that does the job and works fine with any filename is and several times more efficient (no pipes, no subshells, no external commands).

oh and in case you haven't noticed the priginal script do not chancges the extension but appends a new one to it, so "index.htm" becomes "index.htm.php" :P yeah it does the trick but in a very nasty way (also notice that the dot was ommited).

this is the right way to do it:

 for filename in *.htm; do
     mv "$filename" "${filename%.*}".php

that will effective turn "index.htm" to "index.php" in fact you can even wrap it into a function:

 rename_ext() {
     local filename
     for filename in *."$1"; do
         mv "$filename" "${filename%.*}"."$2"

and then you use it like:

 rename_ext htm php

and it work with any extension and any filename.
Posted 2009-02-07 14:52:41
hmm I've just noticed that it does consider the dot in the filename, but it does the wrong way (it's even worse in fact).

the dot is used as the field separator for the awk command, however this means that if the file has more than one dot it will preserve only the first! by example if you have a file named "archive.tar.gz" and you want to rename it to .bz2 this command will turn it into "archive.bz2" not "archive.tar.bz2".
Posted 2009-02-07 15:18:21
I agree your script, is a better and more general method. However you can't simply pass *.htm to awk. This would carry out the awk commands inside the htm files, not to the actual filenames.

My system has the command rename which seems to do the same as your script, it even uses a similar command line structure:

rename .htm .php *.htm
Posted 2009-03-19 10:00:27

Home Latest Browse Top 25 Random Hall Of Fame Contact Submit