++ :) Here's what I did to it:
#!/usr/bin/perl -w
use strict;
use Cwd;
use File::Spec::Functions qw(catdir catfile);
use File::Copy;
use MP3::Info;
die "usage: $0 dirname [dirname ...]\n" unless @ARGV;
my $cwd = cwd();
my %skip;
for(@ARGV) {
chdir($_) or (warn("Couldn't chdir to $_\n"), next);
opendir my($dh), ".";
for my $file (grep /\.mp3\z/i and -f, readdir $dh) {
my ($artist, $title) = @{ get_mp3tag($file) }{qw(ARTIST TITLE)
+};
next unless $artist and $song;
my $dirname = lc $artist;
s/\bthe\s*//g, s/^\s+//g, s/\s+$//g, tr/ /_/ for $dirname;
my $targ_dir = catdir("..", $dirname);
unless($skip{$directory} or -e $targ_dir) {
print "Create $dirname folder (y/n)? ";
<STDIN> =~ /^y/i ? mkdir $targ_dir : undef $skip{$director
+y};
}
if(-d $targ_dir) {
my $target = catfile($targ_dir, "$artist - $title.mp3");
print "$file -> $target\n";
move($file, $target);
}
else {
warn(
"Skipping $file, $directory ",
(-e $targ_dir ?
"is not a directory"
: "was not created"
),
".\n"
);
}
}
chdir($cwd);
}
Untested. :) (I'd modify it further for my own perusal.)
For critique look at the changes. In short: use File::Spec to compose filenames, take arguments from commandline, try to allow for processing more than one thing per call (not an issue in your own situation right now of course, but will likely become and should be taken care of when releasing code), prefer readdir, inform the user well. The %skip bit is thrown in for good measure, so that you don't have to no the same prompt for the same artist ten times in a row if that happens to happen. :)
I'd add a commandline option (Getopt::Std is very easy to incorporate) like -f (= force) that tells the script to just go ahead and create directories without asking. Something like -d dir (= destination directory) would probably be a good idea also. A switch to adjust behaviour between taking artist/song info from filename and/or ID3 could be useful as well.
Makeshifts last the longest. |