Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Re: Copy Mp3s By Genre

by sacked (Hermit)
on Apr 26, 2004 at 22:29 UTC ( #348343=note: print w/replies, xml ) Need Help??

in reply to Copy Mp3s By Genre

Nice work! This looks good, and useful, too. Here are a few suggestions:

You open a filehandle FL to each file you examine, but you never read from it. I would remove the code related to this filehandle:
open(FL, $File::Find::name); ... close(FL);

Inside a subroutine, you should use return rather than next. If you use the code as is, you will see warnings from Perl such as "exiting subroutine via next at line...":

$tag = get_mp3tag($_) or print "Could not access tag on $_\n" and next;
$tag = get_mp3tag($_) or print "Could not access tag on $_\n" and return;

For portability, use File::Spec to generate file or directory names:

use File::Spec::Functions qw(catdir); ... $newdir = catdir( $dstdir => $dir );

File::Path::mkpath raises an exception on error. You'll want to wrap that call in eval. Also, the second argument is a boolean flag that controls printing of the directories as they are created. The third argument is the mode, for which you'll need to have execute permissions on if you want to create subdirectories:
eval { mkpath($newdir, 0, 0755) }; if ($@) { print "canít mkdir $newdir: $@"; }

Finally, as a simple style change, you can reduce the indentation level of the code in your wanted subroutine if you use the statement modifier forms of if/unless.

Here is a different version of your script with the changes described above:
use strict; use MP3::Info; use File::Find; use File::Copy; use File::Basename; use File::Path; use File::Spec::Functions qw(catdir); my $genre = 'Country'; my $srcdir = '/MP3 Test/'; my $dstdir = 'c:/'; find(\&wanted, $srcdir); # note: now vars ($dir, etc.) scoped to subroutine (per Jaap) sub wanted { # anchor regex to end of filename return unless /\.mp3\z/; my $tag = get_mp3tag($_) or print "Could not access tag on $_\n" a +nd return; return unless $tag->{"GENRE"} eq $genre; my $path = $File::Find::name; my $dir = dirname($path); my $newdir= catdir( $dstdir => $dir ); if (! -d $newdir ) { eval { mkpath($newdir, 0, 0755) }; if ($@) { print "canít mkdir $newdir: $@"; } } # don't need basename($path), just pass copy() # a directory as the second argument copy($path => $newdir) or die "copy failed: $!\n"; }

You can make the script even more useful by allowing the user to specify the genre, source directory, and destination directories on the command line.


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://348343]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (5)
As of 2023-04-01 23:44 GMT
Find Nodes?
    Voting Booth?

    No recent polls found