You are not logged in.
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
thx for every comment! :>
Last edited by arch0r (2010-11-28 16:58:01)
Offline
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
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
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
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
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
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!
the script above does it what i was looking for! ... except the mp3s don't get moved into the album
Offline
EasyTAG in extra can do exactly what you need, and a whole lot more
Offline
EasyTAG in extra can do exactly what you need, and a whole lot more
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
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
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 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
thanks a lot for your effort, i really appreciate your work! this script is what i dreamed of
best regards :>
Offline