如何在File :: Find :: Rule中的`or`替代中使用mindepth和maxdepth?

时间:2018-10-05 19:44:38

标签: perl

我具有以下文件夹结构(作为最小示例):

dir
├── a
│   ├── b
│   │   ├── c.txt
│   │   └── d.txt
│   └── c
│       └── q.txt
├── b
│   ├── bb.txt
│   └── d
│       └── dd.txt
└── q.txt

我想查找所有.txt个文件,但使用File::Find::Rule从搜索中排除dir/b中的所有内容(我知道我可以使用File::Find轻松地做到这一点,但这需要大量重构我的代码。

我尝试了以下操作:

use feature qw(say);
use strict;
use warnings;
use File::Find::Rule;

my $dir = 'dir';
my @files = File::Find::Rule->or(
    File::Find::Rule->directory->mindepth(1)->maxdepth(1)
                    ->name( 'b' )->prune->discard,
    File::Find::Rule->name('*.txt'),
)->in( $dir );
say for @files;

输出

dir/q.txt
dir/a/c/q.txt

预期输出

dir/q.txt
dir/a/b/d.txt
dir/a/b/c.txt
dir/a/c/q.txt

maxdepth()函数内部似乎没有mindepth()or()这样的功能。

1 个答案:

答案 0 :(得分:4)

find命令行工具一样,maxdepth并没有限制匹配的发生位置。它限制了实际遍历。

  

maxdepth( $level )

     

在起点以下最多降低$level(非负整数)级目录。

就像find命令行工具一样,mindepth可以防止在一定深度之前执行所有测试。

  

mindepth( $level )

     

请勿以小于$level(非负整数)的水平进行任何测试。

鉴于他们的所作所为,它们会影响整个搜索。因此,使用外部规则对象的mindepthmaxdepth并不奇怪,而其他规则对象则被忽略。 [1]


此处可以使用与find命令行工具相同的解决方案。

find

$ find dir -wholename dir/b -prune -o -name '*.txt' -print
dir/a/b/c.txt
dir/a/b/d.txt
dir/a/c/q.txt
dir/q.txt

File :: Find :: Rule:

$ perl -MFile::Find::Rule -e'
   my ($dir) = @ARGV;
   CORE::say for
      File::Find::Rule
         ->or(
            File::Find::Rule->exec(sub { $_[2] eq "$dir/b" })->prune->discard,
            File::Find::Rule->name("*.txt"),
         )
         ->in($dir);
' dir
dir/q.txt
dir/a/b/c.txt
dir/a/b/d.txt
dir/a/c/q.txt

另一种方法是使用File :: Find :: Rule构建要搜索的目录列表,然后使用File :: Find :: Rule的另一种用法搜索这些目录。 (相当于find ... -print0 | xargs -0 -I{} find {} ...的Perl。)


  1. find命令行实用程序以不同的方式处理放错位置的输入。

    $ find dir -type d -mindepth 1 -maxdepth 1 -name b -prune -o -name '*.txt' -print
    find: warning: you have specified the -mindepth option after a non-option argument (, but options are not positional (-mindepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.
    
    find: warning: you have specified the -maxdepth option after a non-option argument (, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.
    
    dir/q.txt