代码之家  ›  专栏  ›  技术社区  ›  Håkon Hægland

如何在File::Find::Rule中的“or”alternative中使用mindepth和maxdepth?

  •  4
  • Håkon Hægland  · 技术社区  · 6 年前

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

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

    我要找到所有的 .txt 但排除所有文件 dir/b File::Find::Rule (我知道我可以用 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 回复  |  直到 6 年前
        1
  •  4
  •   ikegami    6 年前

    find 命令行工具, maxdepth 不限制匹配发生的位置;它限制了实际的遍历。

    maxdepth( $level )

    最多下降 $level (非负整数)低于起始点的目录级别。

    命令行工具, mindepth 防止在某个深度之前执行所有测试。

    mindepth( $level )

    不要在低于 $级

    考虑到他们所做的,他们会影响整个搜索。因此,这并不奇怪 明德普 最大深度 从外部规则对象是一个使用,其他被忽略。 [1]


    找到

    找到

    $ 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
    

    $ 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的另一种用法搜索这些目录(Perl等价于 find ... -print0 | xargs -0 -I{} find {} ... .)


    1. 这个 找到

      $ 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