tags:

views:

1534

answers:

5
+10  Q: 

bash rename files

in a directory, i have a bunch of *.html files. I'd like to rename them all to *.txt I use the bash shell. Is this easy enough to say how to do?

+1  A: 

You want to use rename :

rename .html .txt *.html

This does exactly what you want - it will change the extension from .html to .txt for all files matching *.html.

Note: Greg Hewgill correctly points out this is not a bash builtin; and is a seperate Linux command. If you just need something on Linux this should work fine; if you need something more cross-platform then take a look at one of the other answers.

Dave Rigby
Although this is a good solution, the `rename` program is not related to `bash` and is also not available on all platforms. I've only seen it on Linux.
Greg Hewgill
"$rename .html .txt *.html" results in...syntax error at (eval 1) line 1, near "."
Amber
@Greg: Ah yes you're right - I'd always assumed it was a bash builtin. However I don't think I've ever come across a Linux system which didn't have it; so if you're only need this for Linux rename is probably the simplest method.
Dave Rigby
yes, rename not available in Mac Terminal
bmw0128
+1  A: 

Unfortunately it's not trivial to do portably. You probably need a bit of expr magic.

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

Remove the echo once you're happy it does what you want.

Edit: basename is probably a little more readable for this particular case, although expr is more flexible in general.

Charles Bailey
+2  A: 
rename 's/\.html$/\.txt/' *.html

does exactly what you want.

Amber
I don't think you can use a literal regex in bash like you suggest - which shell are you using?
Dave Rigby
bash, on Ubuntu (Jaunty).
Amber
i'm using a Mac terminal
bmw0128
Here's the man page for the version of rename on Ubuntu: http://unixhelp.ed.ac.uk/CGI/man-cgi?rename
Amber
(As you can see from the man page, it's tied into perl.)
Amber
rename is a command on some systems. I have a Perl script (originally from the first Camel book) that does the job. There's also a GNU program of the same name that does roughly the same job.My Mac doesn't have a system-provided 'rename' command - or it isn't on my PATH (which is moderately comprehensive).
Jonathan Leffler
+6  A: 

The following would do and does not require the system to have the rename program (although you would most often have this on a system):

for file in *.html; do
    mv "$file" "`basename $file .html`.txt"
done

EDIT: As pointed out in the comments, this does not work for filenames with spaces in them without proper quoting (now added above). When working purely on your own files that you know do not have spaces in the filenames this will work but whenever you write something that may be reused at a later time, do not skip proper quoting.

For an better solution (with only bash functionality, as opposed to external calls), see one of the other answers.

Mikael Auno
Rodrigo Queiro
Only good if the files are all in the current directory, of course, because basename strips off the pathname part. Just a 'beware'!
Jonathan Leffler
if there are many html files, use bash's internal string functions instead of basename.
ghostdog74
+1 for use of basename; although the question specifies it is for the bash shell, portability is good!
akent
This solution is bad, not only because it is slow but because it does not work with filenames with spaces in them. You should ALWAYS do proper quotation in bash scripts. mv "$file" "$(basename "$file" .html)".txt would be much better. But still, mv "$files" "${files%.html}.txt" is much better.
Pozsár Balázs
I agree with Pozsar. If you are not careful, this can really make for a bad day. Just a warning.
Jim
+7  A: 

if using bash, no need for external commands like sed, basename, rename, expr...etc

for files in *.html
do
 mv "$files" "${files%.html}.txt"
done
ghostdog74
++ for idiomatic bash
guns
See Pozar's comment for the reasons why.
Jim