7

I have a large directory of music files whose titles follow the below format:

Title_stringOfNumbers - Artist.mp3

My goal is to remove the underscores followed by numbers and switch the artist's name with the title.

For example, the original filename is:

whats up_7979841261 - randomArtist.mp3

My desired filename:

randomArtist - whats up.mp3

The title can contain special characters (', !, ., _, (, ), /, \ and even Japanese characters) and numbers, but an underscore character and a number are never next to each other in the first part of the filename (so there are no multiple word title_2_6878492178471289 - artist.mp3-like files).

I tried using the rename command in the terminal to remove the underscores so far, but I managed to hit a roadblock, because this line didn't do anything and I'm not familiar with using it.

rename 'y/_//' *

This is all using POP!_OS 21.10, so anything that works with Ubuntu should work with my system too. I used the Perl script rename (installed with sudo apt install rename). However, I found out that all three variants (rename, prename, file-rename) are installed on my system.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
BeanieBarrow
  • 175
  • 5
  • 1
    What operating system are you using? Which rename (see What's with all the renames: prename, rename, file-rename?)? – terdon Jan 20 '22 at 09:18
  • @terdon I'm using POP!_OS 21.10., so anything that works with Ubuntu should work with my system too. I used the Perl script rename (installed with sudo apt install rename). However, I found out that all three of the scripts you linked are installed on my system. – BeanieBarrow Jan 20 '22 at 09:21
  • Perfect, thanks! Are you open to different result file names? What you ask for is perfectly feasible, but having file names with spaces just makes your life difficult and complicates any other future operation you may want to do. I would urge you to think of other formats, for instance randomArtist_-_whats_up.mp3. Just something to think about. – terdon Jan 20 '22 at 09:39
  • Thank you, I'll keep your suggestion in mind in the future, but for now, I'll pass. – BeanieBarrow Jan 20 '22 at 09:55

2 Answers2

14

You can use (Perl) rename:

rename -n 's/^(.*)(_\d+) - (.*)\.mp3$/$3 - $1.mp3/' *.mp3

Remove the -n to actually run the operation if the result looks good.


If your files have correct id3 tags, it might be better to rename using these tags:

e.g. mp3rename or exiftool

sudo apt install mp3rename
mp3rename -s '&a - &t'
mp3rename *.mp3
pLumo
  • 22,565
  • Thank you, it worked flawlessly and I managed to id3 tag my files correctly from filenames after this. Can you explain what each part of this one-liner does, so I can more easily rename files in the future without having to post a question here? – BeanieBarrow Jan 20 '22 at 10:03
  • 2
    More or less basic regex with capturing groups (...). You could check here for good explanation: https://regexr.com/6do4q – pLumo Jan 20 '22 at 21:57
  • 1
    @CoderStudent8822, s is substitute what is between 1st and 2nd / with what is between 2nd and 3rd /. Then the string is spilt in three parts: From start (^), take any number of anything (.*) before a underscore followed by at least one numeral, then there should be a hyphen, then any number of anything folloved by .mp3 (the . is a literal dot, just . means any symbol). The three parts within paranteses are saved, then the entire filename is replaced with what was in the third paranteses ($3) spaces and a hyphen and then what was in the first ($1) then .mp3. HOpe this helps, regexes are great – MortenSickel Jan 21 '22 at 14:02
5

Using a loop, mv and parameter substitution:

for i in *.mp3; do
  a="${i##* - }" # randomArtist.mp3
  n="${i%% - *}" # whats up_7979841261
  t="${a%%.*} - ${n//_[0-9]*/}.mp3" # randomArtist - whats up.mp3
  echo mv -- "$i" "$t" # mv -- randomArtist - whats up.mp3 → whats up - randomArtist.mp3
  # mv -- "$i" "$t"
done

Before applying a good idea is a backup. The actual mv command is commented, if you are happy with what the echo shows, uncomment it and run.