Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. 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 directories with .MP3 files which I'd like to change the extensions to .mp3. What's the easiest way to do this? I'm think something along the lines of:

find /RootPath -type f -iname "*.mp3" -exec mv {} sed s/.*MP3/\1.mp3/ \; 

...though I know that isn't quite right. :) The substitution isn't correct and I'm not sure how to use both a mv and a sed command with -exec in find.

Would I need a bash script for this?

share|improve this question
up vote 9 down vote accepted

Here is one way to do this in Bash:

for i in *; do [ "${i/%MP3/mp3}" != "$i" ] && echo "$i" "${i/%MP3/mp3}"; done

I've used echo here so the command itself doesn't do anything but print pairs of files names. If that list represents the changes you want to make, then you can change echo to something like mv -i -- which will then move your files (and prompt you before overwriting).

Brief Explanation:

The for iterates through every file matched by *. Then, we determine if the extension is already lowercase, if it is we move on, if it isn't, we proceed to move it (or echo it, as the case may be). This uses Bash's built in string operations which you can read about here: http://tldp.org/LDP/abs/html/string-manipulation.html

share|improve this answer
Thanks for your answer and pointing me to a link on bash string manipulation! – user4390 Feb 1 '11 at 22:03

In zsh:

autoload zmv
zmv '(*).MP3' '$1.mp3'   # rename files in the current directory only
zmv '(**/)(*).MP3' '$1$2.mp3'  # rename files in subdirectories as well
share|improve this answer

You could use the rename command for those. For example to change the case of file name extensions from upper to lower, try this:

rename .JPG .jpg *.JPG

Here is some guys tutorial about how he moved from a messy bash script to this simple command for exactly your use-case.

Another fancy command to do this is pax. If you are using ZSH for your shell, you could also use zmove.

share|improve this answer
super! exactly what I needed – JoshP Jun 24 '13 at 21:02

Use perl-rename, swiss army knife of file-renaming with regular expressions (on ubuntu, this is bundled with the perl package as prename):

# Replace prename as appropriate (i.e. if you've got it installed under a different name
find /RootPath -type f -iname '*.mp3' -print0 | xargs -0 prename 's/mp3$/mp3/i'

If you're of the careful sort, use the -n and -v options to perl rename to see what it'll actually do.

share|improve this answer
Thanks for your answer. Don't have perlrename on the server, but I'm going to be playing around it with it later today! – user4390 Feb 1 '11 at 22:03

You need a script, because "extensions" under Linux are actually just parts of the file name string. You have to do some string manipulation in the script to get the new name.

for NAME in *.JPG
    mv "$NAME" "$NEWNAME"

The double-quoting is important if you've got file names with whitespace in them. I thought some of the double-quoting was a bit inobvious.

share|improve this answer
There is nothing wrong per-say with your script but you very defiantly don't need a script for this. There are probably a dozen ways to do it on one line in most shells, and lots of utilities to make it easy too. – Caleb Jun 11 '11 at 19:43

In bash:

# renaming files in the current directory only
for f in *.MP3; do mv "$f" "${f%.MP3}.mp3"; done  

# renaming files in subdirectories as well
for f in *{,/*}.mp3; do mv "$f" "${f%.MP3}.mp3"; done
share|improve this answer

Your Answer


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