Search code examples
linuxbashshellbatch-rename

Batch music directory rename script/command for Linux (bash)


I have a lot of directories which have as name: (YYYY) Artist - Album

Some examples:

(2009) Vengaboys - Greatest Hits!
(2010) AC_DC - Iron Man 2
(2014) Simon & Garfunkel - The Complete Albums Collection
(2014) Various Artists - 100 Hits Acoustic
(2015) Various Artists - Graspop Metal Meeting 1996-2015

How can I best batch rename those directories to following template Artist - Album (YYYY)?

Thus above output should become:

Vengaboys - Greatest Hits! (2009)
AC_DC - Iron Man 2 (2010)
Simon & Garfunkel - The Complete Albums Collection (2014)
Various Artists - 100 Hits Acoustic (2014)
Various Artists - Graspop Metal Meeting 1996-2015 (2015)

Directories not having a (YYYY) prefix should not be modified.

Could someone help me with a linux bash script or sed command to make this happen?


Solution

  • Dealing with spaces and parentheses can be rather tricky with bash. I would use perl for this:

    rename.pl

    #!/usr/bin/perl
    
    use warnings;
    use strict;
    
    opendir my $dh, "./" or die "Unable to opendir : $!";
    for my $dir ( readdir($dh) ) {
        # Skip anything that is not a directory matching '(YYYY) Name' 
        next unless -d "./$dir" and $dir =~ m|^(\(\d{4}\))\s(.*)$|;
        my $new_name = "$2 $1";
        print "'$dir' -> '$new_name'\n";
        rename $dir, $new_name
        or die "Unable to rename '$dir' to '$new_name' : $!";
    }
    

    Generally, life is made easier by sticking to file/directory names without spaces or special characters. Here is how to use it:

    $ ls
    (2009) Vengaboys - Greatest Hits!
    (2010) AC_DC - Iron Man 2
    (2014) Simon & Garfunkel - The Complete Albums Collection
    (2014) Various Artists - 100 Hits Acoustic
    (2015) Various Artists - Graspop Metal Meeting 1996-2015
    rename.pl
    
    $ perl rename.pl
    '(2009) Vengaboys - Greatest Hits!' -> 'Vengaboys - Greatest Hits! (2009)'
    '(2010) AC_DC - Iron Man 2' -> 'AC_DC - Iron Man 2 (2010)'
    '(2014) Simon & Garfunkel - The Complete Albums Collection' -> 'Simon & Garfunkel - The Complete Albums Collection (2014)'
    '(2014) Various Artists - 100 Hits Acoustic' -> 'Various Artists - 100 Hits Acoustic (2014)'
    '(2015) Various Artists - Graspop Metal Meeting 1996-2015' -> 'Various Artists - Graspop Metal Meeting 1996-2015 (2015)'
    
    $ ls
    AC_DC - Iron Man 2 (2010)
    Simon & Garfunkel - The Complete Albums Collection (2014)
    Various Artists - 100 Hits Acoustic (2014)
    Various Artists - Graspop Metal Meeting 1996-2015 (2015)
    Vengaboys - Greatest Hits! (2009)
    rename.pl