Batch rename file extensions

This article describes ways to quickly batch rename the file extension for a number of files. Examples of when this would be useful include changing all files with a .jpeg extension to .jpg or .htm to .html. I will cover ways to batch change all the file extensions to matching files in the current directory, as well as to matching files in the current directory and all subdirectories. I have tested these commands on Windows with Cygwin.

Basic Method

The basic method to do this is as follows:

for f in *.htm ; do echo mv \"$f\" \"${f/.htm/.html}\"; done > extension_rename.txt

This loops through all files with extension .htm and echoes a mv command that renames the current file name f with .htm replaced with .html. The double quotes are used to handle filenames with spaces and are escaped with a \ so that the echo command will output them. One mv command is output per file found.

The entire output of the command is stored in extension_rename.txt which allows you to check whether the generated commands are correct. Once you have confirmed that the rename commands are correct, you can just pipe extension_rename.txt to /bin/bash:

cat extension_rename.txt | /bin/bash

This method will only operate on files found in the current directory.

Using find

If you want to do this for all matching files in the subfolders underneath the current directory as well, then you need to use find as follows:

find -iname '*.htm' | while read f; do echo mv \"$f\" \"${f/.htm/.html}\"; done > extension_rename.txt

The for loop will not properly handle find output with spaces in the file name, which is why I used while read f. This reads each line of find output and puts it into variable f. The appropriate mv command is again echoed. Again, note the double quotes which help to handle file names and paths with spaces.

Using basename

You can also do rename file extensions with basename, although this will be limited to the current directory only as basename strips path information. Here is the command:

for f in *.htm ; do newname=`basename "$f" htm`html; echo mv \"$f\" \"$newname\"; done > extension_rename.txt

The command goes through each file with a .png extension. It creates a newname by using basename to strip off the htm suffix from the file name $f. It appends to the extension-less file name the new extension html. Finally, it echoes the appropriate mv command. Again, the various double quotes are to handle spaces in the filenames. The backticks when assigning the output of basename to newname are to allow the Bash command to be executed before the assignment is made.

About Peter Yu I am a research and development professional with expertise in the areas of image processing, remote sensing and computer vision. I received BASc and MASc degrees in Systems Design Engineering at the University of Waterloo. My working experience covers industries ranging from district energy to medical imaging to cinematic visual effects. I like to dabble in 3D artwork, I enjoy cycling recreationally and I am interested in sustainable technology. More about me...

Feel free to contact me with any questions about this site at [user]@[host] where [user]=web and [host]

Copyright © 1997 - 2021 Peter Yu