Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a directory full of files ending with .xxx. (Apple.xxx, Orange.xxx, Bannana.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
1  
Much the same question and answers at superuser.com/questions/8716/… –  TRS-80 Jul 24 '09 at 9:56

4 Answers 4

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"
 done

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

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

for i in *.xxx; do
    mv "$i" "`basename $i .xxx`.yyy"
done
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 d.xxx [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

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

Your Answer

 
discard

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.