The docs for File::Find are ludicrously bad.
The first example you ever see is: sub wanted {
/^\.nfs.*$/ &&
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
int(-M _) > 7 &&
unlink($_)
||
($nlink || (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))) &&
$dev < 0 &&
($File::Find::prune = 1);
}
However, if you look right at the bottom, you'll see a
snippet like: sub wanted {
-l && !-e && print "bogus link: $File::Find::name\n";
}
which is really what you want to copy...
Tony | [reply] [d/l] [select] |
I don't want to copy anything. I want to write original code that I understand. :)
Can you explain what that last snippet does that we can take advantage of in this situation?
| [reply] |
Ah, but the best way to learn (IMO) is to copy and tweak.
Yes, it spawns a lot of cargo-cult, but not everyone has the time, the effort and the inclination to devour every word of a man page, especially poorly written ones!
So, let's work at tweaking this one:
sub wanted {
-l && !-e && print "bogus link: $File::Find::name\n";
}
perldoc perlfunc will show you a list of all the file test functions available. -l means 'is a symlink' and -e means 'file exists'.
What File::Find does is apply the 'wanted' sub (or any other sub-ref passed) to every file it finds (with $_ locally set as the filename, having chdir-ed to any directory it finds), so in this case it checks first of all if the file is a symlink (-l), and then if the file doesn't actually exist (-e). If this is true then it tells you that that link is broken (using $File::Find::name which is the fully qualified file name, relative to where you are)
So, say we actually wanted to find all .mp3 files. We'd
use something like:
sub wanted {
return unless -f && /\.mp3$/;
print $File::Find::name, "\n";
}
Or, you could push them to an array, or whatever.
Then you just call this as: find (\&wanted, $BASEDIR)
Tony
| [reply] [d/l] [select] |