If I have a group of files with a .htm extention, how can I rename them all to .html?

mv *.htm *.html

does not work.

  • Just for the sake of completeness, ren *.htm *.html will work in Windows. Nov 8, 2014 at 22:27

8 Answers 8


Or, you could use pure bash... (except for mv, that is..)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

and avoid the nasty basename stuff. ;)

Bash has an extensive set of variable expansion options. The one used here, '%', removes the smallest matching suffix from the value of the variable. The pattern is a glob pattern, so ${file%.*} would also work. The '%%' operator removes the largest matching suffix, and is interchangeable in the example above, as the pattern is fixed, ${file%%.*}.html would turn a.b.htm into a.html though.

See the variable substition section of the bash manpage for more neat tricks. There's a lot that can be done within bash directly.


There shouldn't be spaces, newlines or other whitespace in the filenames, but this version of freiheit's answer handles those. It also uses $() instead of backticks for readability along with other benefits.

for file in *.htm
    mv "$file" "$(basename "$file" .htm).html"

Even better - for the special case of just adding on to the end:

for file in *.htm
    mv "$file" "${file}l"

rename(1) is a Perl utility that does exactly what you want. In this case:

rename 's/\.htm$/.html/' *htm

or if you are using sub directories as well

(requires Bash 4.0 and the globstar setting: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm

  • 1
    rename is easier, but isn't a standard unix program; original question doesn't specify which unix. Seems to be "prename" in some places.
    – freiheit
    Jul 19, 2009 at 19:58
  • 2
    rename comes with perl, and basically every unix comes with perl these days.
    – TRS-80
    Jul 19, 2009 at 20:03
  • 3
    yes, but not every unix includes ancillary programs like 'rename' when they put perl on the system. OSX, for instance, doesn't have "rename" on it.
    – freiheit
    Jul 19, 2009 at 21:47
  • 1
    @William: The double asterisk syntax is only available in Bash 4 and up and only if it's turned on with shopt -s globstar (off by default). Also, Linux and Unix have directories rather than folders. Aug 11, 2012 at 23:59
for file in *.htm; do
  mv $file `basename "$file" .htm`.html

Try it with an echo in front of the mv first time around.

The problem with your original is that "mv *.htm *.html" has the *s handled by the shell, so the mv command simply sees a list of all the .htm and .html files in the current directory. In other words, something like "mv foo.htm bar.htm stuff.htm six.htm file.htm". mv only knows how to handle more than 2 arguments if the last one is a directory.

  • 1
    You should quote"$file", to handle spaces. Jul 19, 2009 at 20:34
  • Your description of the original problem should be emphasised more strongly. This shell wildcard expansion behaviour is surprising and not intuitive for somebody coming from Windows land, and understanding what the shell does makes it clear why the original application of mv won't work. Jul 19, 2009 at 21:57

Yet another pure bash example using string replace.

for file in *.htm; do mv $file ${file/htm/html}; done

Extra - this replaces all the occurrences of a string

for file in *.htm; do mv $file ${file//htm/html}; done

If you use Zsh you can use 'zmv'


The best tool is mmv.

mmv \*.htm #1.html

Other examples of use (and of other tools) in "GNU/Linux Command-Line Tools Summary".

  • 1
    Your usage example fails. You need to escape #. Sep 12, 2009 at 23:48
  • No, it works (I ALWAYS test before posting on SuperUser). The need to escape # depends on the shell you use (I use zsh).
    – bortzmeyer
    Sep 13, 2009 at 20:19

The util-linux-ng package (on Fedora) has a rename command similar to the one mentioned by TRS-80. You can use it like this:

rename .htm .html *.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.