in reply to it's been awhile . . .

Geez, that's rough. I think everyone's lost huge amounts of important files at one time or another, I know I've lost a couple of projects myself (no mp3's though :) Looks like you're on Windows from the "C:\my files." The thing on Windows is, you have to remember to do case-insensitive matching. Your script has this line:
if(not(/#/)) {$playlist{$_} = 1}
You need to normalize the filenames before you put them in the hash. You can do this by making them all lowercase. It wouldn't be a bad idea to hang onto the original name too. The hash value seems like a good place to put it:
if(not(/#/)) {$playlist{lc $_} = $_}
Be sure to do a case-insensitive match when searching for mp3 files with readdir:
my @filelist = grep {/\.mp3$/i} readdir FILES;
While we're at it, better make those filenames lowercase too. That means @filelist should become %filelist:
my %filelist = map {(lc $_, $_)} grep {/\.mp3$/i} readdir FILES;
The "map" just changes each filename (from the grep) to a pair of (lowercase filename, filename), which then goes into the hash %filelist. Now, just create a list of the differences:
my %remove;
for (keys %filelist) {
  $remove{$_} = 1 unless $playlist{$_};
}
Now "keys %remove" is the list of files you want to delete (WARNING: not really. It doesn't include the folder name!) Here's a script I made to put all this stuff together. It doesn't skip lines with # though, and it doesn't have pike's advice about trimming whitespace. It's a start though.
use strict ; use warnings ; my $path = '\\\\sephiroth\\pub\\music\\sdb\\ginsu gnives\\' ; my $playlist = '.\\playlist' ; opendir (my $DIR, $path) || die "opendir (\"$path\"): $!\n" ; my %files = map {(lc $_, "$path$_")} grep {/\.mp3$/i && !-d "$path$_"} + readdir $DIR ; closedir ($DIR) ; open (my $PLAYLIST, "<$playlist") || die "open (\"$playlist\"): $!\n" +; my %playlist = map {y/\r\n//d; (lc $_, 1)} <$PLAYLIST> ; close ($PLAYLIST) ; print join ("\n\t", "\%files =", map {"$_ => $files{$_}"} keys %files) +, "\n" ; print join ("\n\t", "\%playlist =", keys %playlist), "\n" ; my %remove ; for (keys %files) { $remove{$_} = 1 unless $playlist{$_} ; } print join ("\n\t", "\%remove =", keys %remove), "\n\n" ; print "unlink $files{$_}\n" for keys %remove ; #unlink $files{$_} for keys %remove ;
Hope that helps. One last thing, though, I have an mp3 called "Seinfeld- Soup Nazi.mp3." Note that there's no space before the first dash. If I put this in the list with the correct spacing (say I hand-typed my list), this mp3 would get deleted even though I definitely want to keep it. What I'm saying is that this whole thing with exact filename matches is maybe not quite the right way to go about deleting files. It could be made to work though, and it has the advantage of not requiring much perl knowledge :). Anyway, glad to hear you haven't given up on perl for good, despite the traumatic loss of mp3's. Perl is a lot easier to learn than C++, IMHO. (I program in both on a daily basis.) Keep the faith!