문제

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.

도움이 되었습니까?

해결책

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
}

다른 팁

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
);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top