LoneRanger has asked for the wisdom of the Perl Monks concerning the following question:

This code is to read the tags from MP3's and then move them into directories based on that. That works just peachy, but my problem is, what if I want to move them into dirs according to album, not artist? I have sat and thought on this extensively and have come up with nothing except putting the album tag into an array or hash (I'm clueless on hashes) and checking against it. If the album is already in the array/hash check for corresponding artists, if so, make your dirs. The other problem with my solution is, what about soundtracks and such, where more than one artist appears on the CD?
#!/usr/bin/perl -w use MP3::Info; use File::Find; use File::Basename; find(\&wanted, "/MP3"); sub wanted { /\.mp3$/ && do { my $tag = &MP3::Info::get_mp3tag($File::Find::name,1,1); $artist = $tag->{ARTIST} or die "$File::Find::name has no TAG info +"; $prev_artist = "me"; my($dir) = $File::Find::dir; $artist =~ s/ /\\ /g; if ($artist ne $prev_artist) { $FName = "\"" . $File::Find::name . "\""; print "I shall be making these directories\: $dir/$artist\n"; qx { mkdir $dir/$artist ; mv $FName $dir/$artist }; $prev_artist = $artist; } } }

Replies are listed 'Best First'.
Re: MP3 Mover script
by athomason (Curate) on Aug 24, 2000 at 14:51 UTC
    1) Presuming you'll be running this more than once, using a hash in the sense you're implying may not help. Since existing albums directories will be present, you need to check for their existence anyway before trying to create them. That can be done with the filetest -d, which implicitly checks for existence as well directory-ness. Just test the directory's existence before attempting to create it each time.

    Using a hash for the files that you *are* moving might speed up your program if you have many tracks going into the same directory, but you'd be lucky to see an improvement, even in a benchmark. Besides, speed doesn't appear to be your primary concern here.

    Also, where are you getting the album information? Your snippet doesn't get it, though MP3::Info allows you to retrieve it from the same hashref.

    2) This sounds more like a design problem than a Perl problem. You need to decide whether you want to sort tracks based on album or artist. Personally, I sort my MP3s by artist then album (i.e. two dirs deep). And yes, soundtracks are difficult. I just have a Soundtrack directory and a directory under that for each movie title.

    Perhaps this (untested) code will help get you on track.

    #!/usr/bin/perl -w use strict; use MP3::Info; use File::Copy; use File::Find; use File::Basename; find(\&wanted, "/MP3"); sub wanted { /\.mp3$/ or return; my $tag = &MP3::Info::get_mp3tag($File::Find::name,1,1); my $artist = $tag->{ARTIST}; my $album = $tag->{ALBUM}; $artist |= "Unknown Artist"; $album |= "Unknown Album"; $artist =~ s/ /\\ /g; $album =~ s/ /\\ /g; my $dir = $File::Find::dir; -d "$artist" or mkdir "$dir/$artist" or die "Couldn't create $dir/$artist: $!"; -d "$artist/$album" or mkdir "$dir/$artist/$album" or die "Couldn't create $dir/$artist/$album: $!"; move $File::Find::name, "$dir/$artist/$album"; }
      The code is for some reason COMPLETELY wacky!! It creates directories that have no discernable name. Just random text...I will look into it again, AFTER I sleep (26 hour uptime) and I fix my now jumbled MP3 dir....

      Here's one for the little kiddies...ALWAYS USE A TEST FOLDER WHEN YOU ARE MESSING WITH SOMETHING YOU DON'T UNDERSTAND!!!.

      I haven't implemented the whole album thing yet. I was trying to decide on this whole thing first. How would I use the -d filetest?? If you look I am actually calling the system mkdir and mv commands as I don't know a "Perl-ish" way of doing it. It seems as though that would help me exponentially.

      Updated: I guess our viewings collided...I didn't catch all of your code...Thanks for your help.