Renaming Linux files that accidentally have multiple .mp3 extensions

7

I screwed up and accidentally have a bunch of files with the extension .mp3.mp3.mp3.mp3

How can I change these, recursively—and over multiple directories—to set them to just .mp3?

user365967

Posted 2014-12-03T00:55:37.390

Reputation: 351

Answers

16

There is a fairly simple solution, which is to just cut off everything from the first ".mp3" and then add ".mp3" back on. So:

for file in $(find . -name "*.mp3"); do mv "$file" "${file%%.mp3*}.mp3"; done

seumasmac

Posted 2014-12-03T00:55:37.390

Reputation: 336

3

Using the rename utility that comes with perl (might be known as perl-rename on some systems), and a shell with ** (zsh, or bash with shopt -s globstar, among others):

rename 's/(\.mp3)+$/.mp3/' /somedir/**/*.mp3

hobbs

Posted 2014-12-03T00:55:37.390

Reputation: 701

2

Using the find command in bash and some creative scripting, this can be magically cleaned up. The following scripts were tested on Mac OS X 10.9.5 but should work fine on Linux as well. First run this as a “dry run” to make sure you are targeting the right files:

find '/path/to/your/files' -type f -name '*.mp3.mp3*' |\
  while read RAW_FILE
  do
    DIRNAME=$(dirname "$RAW_FILE")
    BASENAME=$(basename "$RAW_FILE")
    FILENAME="${BASENAME%%.*}"
    EXTENSION="${BASENAME#*.}"
    echo "mv "${RAW_FILE}" "${DIRNAME}/${FILENAME}".mp3"
  done

You should first change the /path/to/your/files to match the actual path to the affected files on the system. Also note the last line which is an echo of an mv (move) command. I am doing this to make sure that the script is targeting the correct files.

The core find logic is this:

find '/path/to/your/files' -type f -name '*.mp3.mp3*'

Which basically means, “Find all files in the path /path/to/your/files that are actually files (and not directories) that have a filename pattern that matches *.mp3.mp3*. That should catch any/all files that have more than one .mp3 attached to them; .mp3.mp3, .mp3.mp3.mp3, .mp3.mp3.mp3.mp3, .mp3.mp3.mp3.mp3.mp3, etc…

The script won’t bother to deal with files that just have the correct .mp3 which is a definitely speed benefit if you only have a small subset of files misnamed .mp3.mp3.mp3.mp3 instead of having to rename all files with .mp3.

So when you run that you should see a list of “dry run” mv commands that will fix your issue: Find all those multiple .mp3 files and rename them to a proper, singular .mp3.

Now that that works good, just run the final script like this:

find '/path/to/your/files' -type f -name '*.mp3.mp3*' |\
  while read RAW_FILE
  do
    DIRNAME=$(dirname "$RAW_FILE")
    BASENAME=$(basename "$RAW_FILE")
    FILENAME="${BASENAME%%.*}"
    EXTENSION="${BASENAME#*.}"
    mv "${RAW_FILE}" "${DIRNAME}/${FILENAME}".mp3
  done

Note that the last line is the actual, functional mv command. When you run this version of the script your whole directory will be searched for those multiple .mp3 files and then actually run the full mv command to fix the issue.

JakeGould

Posted 2014-12-03T00:55:37.390

Reputation: 38 217

1+1, your answer is better than mine. ;-) – Sirex – 2014-12-03T01:30:16.260