问题
I want to be able to limit Perl's File::Find
to a directory depth (below the specified search) to the specified directory and 1 & 2 subdirectories beneath it.
I want to be able to enumerate the files at the same time, if this is possible.
It must work with absolute paths.
回答1:
This perlmonks node explains how to implement mindepth and maxdepth from GNU's find.
Basically, they count the number of slashes in a directory, and use that to determine the depth. The preprocess function will then only return the values where the depth is smaller than the max_depth.
my ($min_depth, $max_depth) = (2,3);
find( {
preprocess => \&preprocess,
wanted => \&wanted,
}, @dirs);
sub preprocess {
my $depth = $File::Find::dir =~ tr[/][];
return @_ if $depth < $max_depth;
return grep { not -d } @_ if $depth == $max_depth;
return;
}
sub wanted {
my $depth = $File::Find::dir =~ tr[/][];
return if $depth < $min_depth;
print;
}
Tailored to your case:
use File::Find;
my $max_depth = 2;
find( {
preprocess => \&preprocess,
wanted => \&wanted,
}, '.');
sub preprocess {
my $depth = $File::Find::dir =~ tr[/][];
return @_ if $depth < $max_depth;
return grep { not -d } @_ if $depth == $max_depth;
return;
}
sub wanted {
print $_ . "\n" if -f; #Only files
}
回答2:
Here is another solution that determines the current depth within File::Find::find
by counting the number of directories returned by File::Spec->splitdir
, which should be more portable than counting slashes:
use strict;
use warnings;
use File::Find;
# maximum depth to continue search
my $maxDepth = 2;
# start with the absolute path
my $findRoot = Cwd::realpath($ARGV[0] || ".");
# determine the depth of our beginning directory
my $begDepth = 1 + grep { length } File::Spec->splitdir($findRoot);
find (
{
preprocess => sub
{ @_ if (scalar File::Spec->splitdir($File::Find::dir) - $begDepth) <= $maxDepth },
wanted => sub
{ printf "%s$/", File::Spec->catfile($File::Find::dir, $_) if -f },
},
$findRoot
);
来源:https://stackoverflow.com/questions/9919909/when-using-perls-filefind-whats-a-quick-easy-way-to-limit-search-depth