You are not logged in.

#1 2010-11-27 09:21:18

arch0r
Member
From: From the Chron-o-John
Registered: 2008-05-13
Posts: 597

[SOLVED] Automatically rename folder, create subfolder and move files

Hey all :>

my music directory is a bit messed up and untidy. all albums were encoded into one single folder:

$artist - $album ($year)
Aerosmith - Toys in the Attic (1975)

how can i create a parent folder with the name of the artist (here: Aerosmith), a subfolder for the album without the year (Toys in the Attic) and move all mp3's into it? i have no idea how to handle filenames with bash sad

thx for every comment! :>

Last edited by arch0r (2010-11-28 16:58:01)

Offline

#2 2010-11-27 09:32:51

ChoK
Member
From: France
Registered: 2008-10-01
Posts: 346

Re: [SOLVED] Automatically rename folder, create subfolder and move files

you can try the GTK app metamorphose2 (in AUR I think) or QT app Krename, they will do what you want in a GUI

For bash, you can use sed (get the part before the - store it in $artist, then same for second part) and nested for loop to do what you want, but scripting language like perl/python may be more flexible.


Ah, good taste! What a dreadful thing! Taste is the enemy of creativeness.
Picasso
Perfection is reached, not when there is no longer anything to add, but when there is no longer anything to take away.
Saint Exupéry

Offline

#3 2010-11-27 15:30:54

Cyrusm
Member
From: Bozeman, MT
Registered: 2007-11-15
Posts: 1,053

Re: [SOLVED] Automatically rename folder, create subfolder and move files

I've hacked together a perl script that will create the right directory structure. but I don't have time right now to write up moving the files and destroying the previous directory structure.
I'll post what I have and then get back to it this afternoon when I have time.  (oh yeah, and if anyone want's to continue on my progress feel free.)

#!/usr/bin/perl
use strict;
use warnings;

chdir "music" or die "cuidado! $!";
my @directories = glob "*";
my @artists;
my %albumhash;

foreach(@directories)
{
    push(@artists,split(/ - /,$_));
}
while(@artists)
{
    my $key = shift(@artists);
    my $value = shift(@artists);
    push(@{$albumhash{$key}}, $value);
}

foreach(keys %albumhash)
{
    mkdir $_,0755 or die "couln't makedir\n";
    chdir $_;
    foreach(@{$albumhash{$_}})
    {
        my $dirname = substr($_,0,(length($_) - 7));
        mkdir $dirname,0755 or die "couldn't make subdir\n";
    }
    chdir "..";    
}

This code works assuming that the entire collection of directories is in the format that you stated.  the moving files around might take some work, since all of your directory names are chock full o' spaces :\

Last edited by Cyrusm (2010-11-27 17:18:35)


Hofstadter's Law:
           It always takes longer than you expect, even when you take into account Hofstadter's Law.

Offline

#4 2010-11-27 17:28:15

GogglesGuy
Member
From: Rocket City
Registered: 2005-03-29
Posts: 610
Website

Re: [SOLVED] Automatically rename folder, create subfolder and move files

Goggles Music Manager can do this as well. Basically you first import all the tracks, then after making sure all tags are correctly set, you can tell it to update the filename for all tracks (in the Edit track dialog) according to the desired filename template.

( And if your tags are not set correctly, you can also import the files using a specific template. After that you can write out correct tags as well. See http://code.google.com/p/gogglesmm/wiki/Import )

Last edited by GogglesGuy (2010-11-27 17:30:56)

Offline

#5 2010-11-27 18:25:02

juster
Forum Fellow
Registered: 2008-10-07
Posts: 195

Re: [SOLVED] Automatically rename folder, create subfolder and move files

Here is another perl script, it is pretty simple. I usually make scripts do a dry-run first. You will have to comment out the print statement and uncomment the rename once you are satisfied it works well. You might have to tweak the regexp.

#!/usr/bin/perl

use warnings;
use strict;

my $srcdir = shift @ARGV or die "Usage: $0 <music dir>\n";
opendir my $musdir, $srcdir or die "opendir: $!";

ALBUM_LOOP:
for ( grep { -d "$srcdir/$_" } grep { !/^[.]/ } readdir $musdir ) {
    unless ( /^(.+?) - (.+?) [(]\d+[)]$/ ) {
        warn "Could not match directory: $_\n";
        next ALBUM_LOOP;
    }

    unless ( -d "$srcdir/$1" ) {
        mkdir "$srcdir/$1", 0755 or die "mkdir $1: $!";
    }

    print "$_ -> $1/$2\n";
#     rename "$srcdir/$albumdir", "$srcdir/$1/$2" or die "rename: $!";
}

Offline

#6 2010-11-27 18:47:25

crouse
Arch Linux f@h Team Member
From: Iowa - USA
Registered: 2006-08-19
Posts: 907
Website

Re: [SOLVED] Automatically rename folder, create subfolder and move files

Here is a bash version.

Set the path in the script to your music directory.

I recommend testing it to make sure it's doing what you want on a test set of data.
It worked for my test set of data .... but mine might be different than yours.
Mine assumes that while the albums were all encoded in one directory, the mp3's where placed
in the correct album.

I tried to comment what it was doing for clarity.
As always, use at your own risk, I take no responsibility if it doesn't do what your wanting.

#!/bin/bash
# 11-27-2010 crouse
# Fix Music Directory
# SET PATH TO YOUR MUSIC DIRECTORY HERE !
cd /home/someone/Music/

# Set input file seperator to newline
IFS='
'

# Create album.list if it doesn't exist
if [ -a album.list ];then
 echo "album.list exists"
else
 echo "creating album.list"
for i in `ls -1`
 do
  echo $i >> album.list
 done
fi

# Loop through album list and "do stuff".
while true; do
 read ALBUM || break

   # Get the Artist and remove trailing space
   ARTIST=`echo $ALBUM | awk -F'-' '{print $1}' | sed -e "s/ \{1,\}$//"`

   # Convert to lower case for consistency
   ARTIST=`echo $ARTIST | tr '[:upper:]' '[:lower:]'`

   # Make directory if it doesn't exist already
   mkdir -p $ARTIST

   # Use Bash parameter expansion to rename albums and remove trailing space
   RENAME_ALBUM=`echo ${ALBUM%(*} | sed -e "s/ \{1,\}$//"`
   mv $ALBUM $RENAME_ALBUM

   # Move Renamed ALBUM to ARTIST dir
   mv $RENAME_ALBUM/ $ARTIST/

done < album.list
rm album.list

Last edited by crouse (2010-11-27 19:11:11)

Offline

#7 2010-11-28 10:01:01

arch0r
Member
From: From the Chron-o-John
Registered: 2008-05-13
Posts: 597

Re: [SOLVED] Automatically rename folder, create subfolder and move files

Cyrusm wrote:

I've hacked together a perl script that will create the right directory structure. but I don't have time right now to write up moving the files and destroying the previous directory structure.
I'll post what I have and then get back to it this afternoon when I have time.  (oh yeah, and if anyone want's to continue on my progress feel free.)

#!/usr/bin/perl
use strict;
use warnings;

chdir "music" or die "cuidado! $!";
my @directories = glob "*";
my @artists;
my %albumhash;

foreach(@directories)
{
    push(@artists,split(/ - /,$_));
}
while(@artists)
{
    my $key = shift(@artists);
    my $value = shift(@artists);
    push(@{$albumhash{$key}}, $value);
}

foreach(keys %albumhash)
{
    mkdir $_,0755 or die "couln't makedir\n";
    chdir $_;
    foreach(@{$albumhash{$_}})
    {
        my $dirname = substr($_,0,(length($_) - 7));
        mkdir $dirname,0755 or die "couldn't make subdir\n";
    }
    chdir "..";    
}

This code works assuming that the entire collection of directories is in the format that you stated.  the moving files around might take some work, since all of your directory names are chock full o' spaces :\


wow guys you are really great! thx a lot for your work and responses! smile
the script above does it what i was looking for! yikes ... except the mp3s don't get moved into the album sad

Offline

#8 2010-11-28 14:37:07

nixpunk
Member
Registered: 2009-11-23
Posts: 271

Re: [SOLVED] Automatically rename folder, create subfolder and move files

EasyTAG in extra can do exactly what you need, and a whole lot more wink

Offline

#9 2010-11-28 14:49:21

Runiq
Member
From: Germany
Registered: 2008-10-29
Posts: 1,053

Re: [SOLVED] Automatically rename folder, create subfolder and move files

So can picard.

Offline

#10 2010-11-28 15:16:22

arch0r
Member
From: From the Chron-o-John
Registered: 2008-05-13
Posts: 597

Re: [SOLVED] Automatically rename folder, create subfolder and move files

nixpunk wrote:

EasyTAG in extra can do exactly what you need, and a whole lot more wink

i use easytag for tagging but how can i export files in a specific folder structure? i thought easytag can just edit and save tags!?

Offline

#11 2010-11-28 15:28:32

Cyrusm
Member
From: Bozeman, MT
Registered: 2007-11-15
Posts: 1,053

Re: [SOLVED] Automatically rename folder, create subfolder and move files

ha yeah sorry, I only had a small amount of time to work on it.  all that needs to be accomplished is the moving of files from the original directories to the newly created directories and then deleting the old directories.

I just managed to finish and test this.  make sure that every directory is in the format $artist - $album ($year) or it won't work!

so if you had run my half script, you will probably want to rm those directories

#!/usr/bin/perl
use strict;
use warnings;
use File::Copy; 

chdir "music" or die "cuidado! $!";
my @directories = glob "*";
my @artists;
my %albumhash;

foreach(@directories)
{
    push(@artists,split(/ - /,$_));
}
while(@artists)
{
    my $key = shift(@artists);
    my $value = shift(@artists);
    push(@{$albumhash{$key}}, $value);
}

foreach(keys %albumhash)
{
    mkdir $_,0755 or die "couln't makedir\n";
    chdir $_;
    foreach(@{$albumhash{$_}})
    {
        my $dirname = substr($_,0,(length($_) - 7));
        mkdir $dirname,0755 or die "couldn't make subdir\n";
    }
    chdir "..";    
}
foreach(@directories)
{

    my $current = $_;
    my $targetdir = substr($_,0,(index($_,'-') - 1)) . "/" . substr($_,(index($_,'-')+2),(index($_,'(') - index($_,'-') - 3));
    chdir $current;
    my @musicfiles = glob("*");
    chdir "..";
    foreach(@musicfiles)
    {
        my $old = "$current/$_";
        my $new = "$targetdir/$_";
        move($old,$new) or die "Danger Will Robinson! $!";
    }
    rmdir($current);
}

Hofstadter's Law:
           It always takes longer than you expect, even when you take into account Hofstadter's Law.

Offline

#12 2010-11-28 15:53:44

Cyrusm
Member
From: Bozeman, MT
Registered: 2007-11-15
Posts: 1,053

Re: [SOLVED] Automatically rename folder, create subfolder and move files

eh, figured I'd make it a little more elegant and add some directory checks. this should work for all cases theoretically so that if you add music later on you can update your directories
preconditions: newly added directories are in the format that was prescribed by you and the output doesn't contain any dashes. (I based my glob off of the presence of a dash.)

#!/usr/bin/perl
use strict;
use warnings;
use File::Copy; 

chdir "music" or die "cuidado! $!";
my @directories = glob "*-*";
my @artists;
my %albumhash;

foreach(@directories)
{
    push(@artists,split(/ - /,$_));
}
while(@artists)
{
    my $key = shift(@artists);
    my $value = shift(@artists);
    push(@{$albumhash{$key}}, $value);
}

foreach(keys %albumhash)
{
    if(!(-d $_))
    {
        mkdir $_,0755 or die "couln't makedir\n";
    }
    chdir $_;
    foreach(@{$albumhash{$_}})
    {
        my $dirname = substr($_,0,(length($_) - 7));
        if(!(-d $dirname))
        {
            mkdir $dirname,0755 or die "couldn't make subdir\n";
        }
    }
    chdir "..";    
}
foreach(@directories)
{

    my $current = $_;
    my $targetdir = substr($_,0,(index($_,'-') - 1)) . "/" . substr($_,(index($_,'-')+2),(index($_,'(') - index($_,'-') - 3));
    chdir $current;
    my @musicfiles = glob("*");
    chdir "..";
    foreach(@musicfiles)
    {
        my $old = "$current/$_";
        my $new = "$targetdir/$_";
        move($old,$new) or die "Danger Will Robinson! $!";
    }
    rmdir($current);
}

Thanks for the fun distraction, normally I don't like being someone's personal army but you caught me during my vacation smile  you should be receiving my bill via e-mail (just kidding):D

Last edited by Cyrusm (2010-11-28 16:01:53)


Hofstadter's Law:
           It always takes longer than you expect, even when you take into account Hofstadter's Law.

Offline

#13 2010-11-28 16:57:40

arch0r
Member
From: From the Chron-o-John
Registered: 2008-05-13
Posts: 597

Re: [SOLVED] Automatically rename folder, create subfolder and move files

thanks a lot for your effort, i really appreciate your work! this script is what i dreamed of smile big_smile

best regards :>

Offline

Board footer

Powered by FluxBB