use File::Find; find(\&wanted, 'dir1', 'dir2'...); sub wanted { ... } use File::Find; finddepth(\&wanted, 'dir1', 'dir2'...); # traverse depth-first sub wanted { ... }
find() is similar to the UNIX
find(1) command in that it traverses the specified
directories, performing whatever tests or other actions you request. However,
these actions are given in the subroutine, wanted(), which
you must define (but see find2perl below). For example, to
print out the names of all executable files, you could define
wanted() this way:
sub wanted {
print "$File::Find::name\n" if -x;
}$File::Find::dir contains the current directory name, and
$_ the current filename within that directory.
$File::Find::name contains
"$File::Find::dir/$_". You are chdired to $File::Find::dir when
find() is called. You can set
$File::Find::prune to true in wanted() in
order to prune the tree; that is, find() will not descend
into any directory when $File::Find::prune is set.
This library is primarily for use with the find2perl(1) command,
which is supplied with the standard Perl distribution and converts a
find(1) invocation to an appropriate wanted() subroutine.
The command:
find2perl / -name .nfs\* -mtime +7 \
-exec rm -f {} \; -o -fstype nfs -pruneproduces something like:
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);
}Set the variable $File::Find::dont_use_nlink if
you're using the AFS.
finddepth() is just like find(), except that it does a
depth-first search.
Here's another interesting wanted() function. It will find all
symbolic links that don't resolve:
sub wanted {
-l and not -e and print "bogus link: $File::Find::name\n";
}