http://www.perlmonks.org?node_id=854570

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

Hi all. i am actually trying a program which searched my whole computer for Mp3 files. I am able to search for only a particular drive. I am using windows. And here is my code

#!/usr/bin/perl use warnings; my @content =( "Artist","Title","Album","Year","Genre"); use MP3::Tag; # import module @files = <c:/*.mp3>; # find MP3 files in current directory #i want to search my whole computer instead of a particular drive..How +????? # loop over file list # print tag information foreach (@files) { $mp3 = MP3::Tag->new($_); $mp3->get_tags(); if (exists $mp3->{ID3v1}) { #print $_, "\n", #print "Filename: $filename\n"; print "Artist: " . $mp3->{ID3v2}->artist . "\t"; #print "Length", $mp3 ->{ID3v1}->duration(hh:mm:ss) "\n"; print "Title: " . $mp3->{ID3v1}->title . "\t"; print "Album: " . $mp3->{ID3v1}->album . "\t"; print "Year: " . $mp3->{ID3v1}->year . "\t"; print "Genre: " . $mp3->{ID3v1}->genre . "\n";

Also can anybody give me some ideas of how to search for all music files in my Computer? plz spread the wisdom...Thanks in advance.

Replies are listed 'Best First'.
Re: Searching for a music files
by dasgar (Priest) on Aug 12, 2010 at 04:42 UTC

    I would recommend that you check out File::Find. I've only used this once or twice and I'm not too familiar with the *nix find command, so I'm not the best person to explain how to use this module.

    Basically, File::Find will search through the file system and take an action on files that meet the criteria that you set.

      It's really not complicated, but maybe the example code below will help to understand the documentation ...

      Rata

      use strict; use warnings; use File::Find; my $path = "d://changma_ha"; find(\&checkFile, $path); exit 0; sub checkFile { my $fullfilename = $File::Find::name; # with the full path my $filename = $_; # just the filename if ($filename =~ /\.mp3$/ ) # name ends with .mp3 { print "Finally found $fullfilename\n"; } }
Re: Searching for a music files
by hawtin (Prior) on Aug 12, 2010 at 08:18 UTC

    You should check out File::Find, it is the right way to do it. However I personally don't use it. At this node 823779 the function list_mp3_files() does exactly what you want.

Re: Searching for a music files
by ikegami (Patriarch) on Aug 12, 2010 at 04:34 UTC
    Change
    @files = <c:/*.mp3>;
    to
    @files = <c:/*.mp3 d:/*.mp3>;
    Adjust as needed.

      Thank Ikegami for your suggestion..but i have a question.suppose i have the aaa.mp3 file in a folder name "JAM" under D:/ drive . it is not able to find that file...actually i want my output to be all the file that are present in my computer where ever they are( how much depth thy may be lying)..waiting for ur suggestion..

Re: Searching for a music files
by Marshall (Canon) on Aug 13, 2010 at 08:31 UTC
    I think we've got some fine suggestions in this thread. I was thinking about another problem that could rear its ugly head: how do you find the drives that you want to do complete searches upon?

    Windows drive letter assignments can move around for various reasons. So I hacked out this thing to get a listing of the drives on my system. You might find something like this helpful? I'm sure that there is some better / faster way to do this as this is slow, but it appears to work... Have fun if its helpful..

    Update: As per testing from Ratazong, code works but you have to have admin rights to run fsutil. So I went searching for another way...

    I don't think that the "vol" command requires any special rights to run as it appears in the standard list of command when you type "help" at the command prompt. Using the ouput is a bit trickier because you have to use information from both STDERR and STDOUT but from that info you can glean the 3 possibilities (a) device exists but no media in it, (b) this is something that looks like a hard drive, (c) no device exists. Code shown below. Not quite as much info as the fsutil code, but probably close enough for most purposes.

    #!/usr/bin/perl -w use strict; #find Windows drive letters and type of drive my $result = `fsutil fsinfo drives`; my @letters = ($result =~ /[A-Z]{1}:/g); my %drive_types; foreach my $ltr (@letters) { my $result = `fsutil fsinfo drivetype $ltr`; $result =~ s/\r\n$//; my $type = ($result =~ /-\s+(.*)/)[0]; $drive_types{$ltr}=$type; } foreach my $drive (sort keys %drive_types) { print "$drive is a $drive_types{$drive}\n"; } __END__ prints: A: is a Removable Drive C: is a Fixed Drive D: is a CD-ROM Drive E: is a Removable Drive F: is a Removable Drive H: is a Fixed Drive I: is a Fixed Drive
    my %drives; foreach my $drive ('A'..'Z') { my $all = `vol $drive: 2>&1`; next if ($all =~ m/system cannot find the path/); $drives{$drive} = ($all =~ /^\s*(.*)/)[0]; #first line } foreach my $drive (sort keys %drives) { print "$drive: $drives{$drive}\n"; } __END__ #prints........... A: The device is not ready. C: Volume in drive C is Main-Max D: The device is not ready. E: The device is not ready. F: The device is not ready. G: Volume in drive G is CIS27 H: Volume in drive H is Sata-1a I: Volume in drive I is SATA-1B