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

i'm trying to make a script that will go through my winamp playlist and through my mp3 directory. it'll then compare the two lists, and if there are any files in the directory that aren't in the playlist, they'll be deleted. hehe, trying to clean up the stuff i don't want anymore. but unfortunately it isn't doing that, and hence i find myself here, begging knowledge. i think the problem is in the if statement, but that's about all i can figure out after staring at it for several hours and asking my programmer friend for help as well.
use strict; open(PLAYLIST, "<playlist.m3u"); opendir(FILES, 'd:\my files'); my @playlist = (); my @filelist = grep {/\.mp3$/} readdir FILES; my $song; while(<PLAYLIST>) { if(not(/#/)) {push(@playlist, $_)} } foreach $song(@filelist) { if(grep($song, @playlist) == 0) { unlink($song) } } closedir FILES; close PLAYLIST;

Replies are listed 'Best First'.
Re: comparing two lists
by particle (Vicar) on Jun 24, 2001 at 03:49 UTC
    i love map. this is a great example of why. actually, you're using grep, which is very similar to map. but it's all in how you use it.

    you may get some milage out of this code. i grabbed it from the snippets section some time ago.

    # Determining whether an item is in a list my @items = ('bbb', 'ddd'); my @list = ('aaa', 'bbb', 'ccc', 'ddd', 'eee'); foreach $item (@items) { if ({ map { $_ => 1 } @list }->{$item}) { print "Yes!\n"; } else { print "No!\n"; } }
    it's recycled from somewhere in the snippets section. also, you might want to look at:
    diff of two hashes and a few others. try a search on 'diff hash' for more clues.

    ~Particle

Re: comparing two lists
by thraxil (Prior) on Jun 24, 2001 at 04:36 UTC

    this works for me:

    use strict; open(PLAYLIST, "<playlist.m3u"); opendir(FILES, 'd:\my files'); my %playlist ; my @filelist = grep {/\.mp3$/} readdir FILES; my $song; while(<PLAYLIST>) { chomp; if(not(/#/)) {$playlist{$_} = 1} } foreach $song(@filelist) { if(!exists $playlist{$song}) { unlink($song) } } closedir FILES; close PLAYLIST;

    hashes are sweet. (and notice the chomp)

    anders pearson

      hm . . . ok, that works, except for the part where it deletes the file. it's weird. if i change unlink($song) to, say, print $song, it prints the filenames. but for some reason, unlink($song) doesn't work
        If you use print $song, it prints the filenames, but not the full paths, right? Since the file is not in the current working directory, you need to use the path with the filename so that Perl knows where to find the file.
        my $dir = 'd:\my files'; opendir(FILES, $dir) or die "Can't opendir '$dir': $!\n"; # read in the playlist and the files, create the hash, and so on... foreach $song(@filelist) { if(!exists $playlist{$song}) { unlink("$dir/$song") or warn "Can't unlink '$dir/$song': $!\n"; } }
Re: comparing two lists
by Beatnik (Parson) on Jun 24, 2001 at 12:25 UTC
    Our very own davorg wrote Array::Compare...
    #!/usr/bin/perl -w use strict; use Array::Compare; my @arr1 = 0 .. 10; my @arr2 = 0 .. 10; my $comp = Array::Compare->new; if ($comp->compare(\@arr1, \@arr2) { print "Arrays are the same\n"; } else { print "Arrays are different\n"; }
    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.
Re: comparing two lists
by scottstef (Curate) on Jun 24, 2001 at 19:21 UTC
    I recently did something similar comparing items that were in two different files using hashes. Each hash had a primary key that was the list name with a value of 1 if it exixted in the first file, 2 if it existed in both files, and 3 if it was only in the secoond file.

    my $file1 = "/home/scott/file1"; my $file2 = "/home/scott/file2"; my $hashOfLists; my %hashOfLists; open (FILE1, "$file1") or die "Could not open $file1 $!"; open (FILE2, "$file2") or die "Could not open $file2 $!"; ###################################################### #####This block reads all of the items of the file into #####a hash with the item being the key. Since I ##### was comparing 2 files each key received a #####value of 1 if it was in the first file, 2 if #####it was in both , and 3 if it was only in file 2 ###################################################### foreach (<FILE1>) { chomp $_; $hashOfLists{$_} =1; } foreach (<FILE2>) { chomp $_; ###################################################### #####if exists checks the hash to see if $_ exists. ##### If true $_'s value becomes 2, #####if false, $_ gets a value of three ###################################################### if (exists $hashOfLists{$_}) { ($hashOfLists{$_}) =2; } else { ($hashOfLists{$_})=3; } } close FILE1 or die "Could not close $file1 $!"; close FILE2 or die "Could not close $file2 $!";

    "The social dynamics of the net are a direct consequence of the fact that nobody has yet developed a Remote Strangulation Protocol." -- Larry Wall