When using Perl's File::Find what's a quick & easy way to limit search depth?

家住魔仙堡 提交于 2019-12-10 18:59:16

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!