vote up 9 vote down star
3

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.

flag

7 Answers

vote up 14 vote down check

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 replacement options. The one used here, '%', removes the smallest matching pattern from the. Pattern in this case is a glob pattern, so ${file%.*} would also work. The '%%' operator removes the largest matching pattern, 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.

link|flag
vote up 6 vote down

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
do
    mv "$file" "$(basename "$file" .htm).html"
done
link|flag
vote up 6 vote down
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

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.

link|flag
1  
You should quote"$file", to handle spaces. – Richard Hoskins Jul 19 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. – Greg Hewgill Jul 19 at 21:57
vote up 5 vote down

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

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

link|flag
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 at 19:58
1  
rename comes with perl, and basically every unix comes with perl these days. – TRS-80 Jul 19 at 20:03
2  
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 at 21:47
vote up 0 vote down

If you use Zsh you can use 'zmv'

link|flag
vote up 0 vote down

The best tool is mmv.

mmv \*.htm #1.html

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

link|flag
Your usage example fails. You need to escape #. – Cristian Ciupitu Sep 12 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 at 20:19
vote up 0 vote down

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
link|flag

Your Answer

Get an OpenID
or
never shown

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