При использовании Perl File :: Find, что является быстрым и простым способом ограничения глубины поиска? - PullRequest
3 голосов
/ 29 марта 2012

Я хочу иметь возможность ограничить Perl File::Find до глубины каталога (ниже указанного поиска) указанным каталогом и 1 & 2 подкаталогов под ним.

Я хочучтобы иметь возможность перечислять файлы одновременно, если это возможно.

Он должен работать с абсолютными путями.

Ответы [ 2 ]

5 голосов
/ 29 марта 2012

Этот узел perlmonks объясняет, как реализовать mindepth и maxdepth из поиска GNU.

По сути, они подсчитывают количество слешей в каталоге и используют их для определения глубины.Функция preprocess будет возвращать только те значения, глубина которых меньше 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;
}

С учетом вашего случая:

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
}
3 голосов
/ 26 сентября 2013

Вот еще одно решение, которое определяет текущую глубину в File::Find::find путем подсчета количества каталогов, возвращаемых File::Spec->splitdir, которое должно быть более переносимым, чем подсчет слешей:

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
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...