Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a directory full of files ending with .xxx. (,,

I want to change their extensions to .yyy. (Apple.yyy, Orange.yyy, Bannana.yyy)

What's the quickest way to accomplish this using basic shell commands?

share|improve this question
Much the same question and answers at… – TRS-80 Jul 24 '09 at 9:56
up vote 14 down vote accepted

Take a look at the rename command: rename .xxx .yyy *.xxx

share|improve this answer
Works like a charm! Thanks for introducing me to the rename command. – Runcible Jul 23 '09 at 21:27
Rename is good too :-) – Kyle Brandt Jul 23 '09 at 21:28
On debian varieties, rename actually accepts a regular expression, which allows you do some pretty powerful renaming. – Chad Huneycutt Jul 23 '09 at 21:29
On Fedora, the rename command is included in the util-linux-ng package. – Cristian Ciupitu Sep 12 '09 at 21:47
 for i in *.xxx; do 
     mv "$i" "${i%.*}.yyy"

The percent sign in "${i%.*}" means use the glob pattern that is after the percent sign, apply it to the value of the variable i, and remove the shortest possible match from the tail end of that value. This called Parameter / Variable expansion, and has many uses. You can also make it so the glob is longest possible match or make the glob match from the start as well. This Linux Journal article is all about parameter expansion.

It is put in double quotes so that if there are spaces in the filename and the IFS variable is set to include spaces (the norm), the filename will still be passed to mv as one argument.

share|improve this answer

Install mmv and then do this:

mmv -r "*.xxx" "#1.yyy"
share|improve this answer
mmv can also change all filenames in lowercase: mmv "*" "#l1" – ThorstenS Jul 23 '09 at 21:30
Thank you for mentioning this command. It's the first time I've heard about it and it's included in Fedora, too (the mmv package). – Cristian Ciupitu Sep 12 '09 at 21:29

Already a bunch of answers, but I'll add my own.

for i in *.xxx; do
    mv "$i" "`basename $i .xxx`.yyy"
share|improve this answer
Basename is probably not builtin to the shell ( to see, use the 'which basename' ). So it might be a touch slower, it is however, a lot easier to read and remember :-) So you get my upvote. – Kyle Brandt Jul 24 '09 at 14:13
You have an error syntax in for $i .... It should be for i.... Even after correcting this, the script fails if the file names contain multiple spaces, e.g. c [you're seeing only 1 space because of formatting limitations]. To fix this error, you need to put the $i parameter of basename inside quotes. – Cristian Ciupitu Sep 12 '09 at 21:35

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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