A command to change a set of files' extension

Mar 14, '05 09:27:00AM

Contributed by: possen

I have wanted a way to rename all files with one extension to another extension for some time now ... and finally figured out a way to do so without writing a script. The first thing most people think of is something like mv *.txt *.rtf, but that will never work because the targets will not expand the wildcard in that way. Next you might try xargs or find with -exec, but the extension becomes a problem because you can only append to it. The solution: the following command will rename all the files in the folder with the .txt extension to .rtf:

ls *.txt | sed 's/\(.*\)\.txt/  & \1.rtf/' | xargs -L1 mv
This can be applied to other commands like find instead, so be careful:
 find . -name '*.txt' -print | sed 's/\(.*\)\.txt/  & \1.rtf/' | \
 xargs -L1 mv
The above command would run for a whole subdirectory. Depending on where you are in the hierarchy, you could rename all the .txt files on your hard disk! The final command in xargs tells it what to do. You could replace that with something other than mv, like cp or diff; pretty much any command that takes two arguments.

The first part of the command locates the files with the particular extension. The sed command then uses a regular expression to build a set of arguments replacing the original with the replacement. The xargs bit executes the command, once for each line with the arguments generated by sed.

Once again, please be careful with this, it is powerful. You might want to test the final command with echo until you are sure you are getting the right set of files and replacements. So to be safe:
 find . -name '*.txt' -print | sed 's/\(.*\)\.txt/  & \1.rtf/' | \
 xargs -L1 echo mv 
[robg adds: I haven't tested this one...]

Comments (28)

Mac OS X Hints