我如何使用$ File :: Find :: prune?

the*_*eid 4 perl

我需要在第一个目录中编辑cue文件,而不是在子目录中递归.

find(\&read_cue, $dir_source);
sub read_cue {
    /\.cue$/ or return;

    my $fd = $File::Find::dir;
    my $fn = $File::Find::name; 
    tie my @lines, 'Tie::File', $fn
      or die "could not tie file: $!";

    foreach (@lines) {
        s/some substitution//;
    }

    untie @lines;
}
Run Code Online (Sandbox Code Playgroud)

我尝试过变种

$File::Find::prune = 1;
return;  
Run Code Online (Sandbox Code Playgroud)

但没有成功.我应该在哪里放置和定义$File::Find::prune

谢谢

msw*_*msw 7

如果你不想递归,你可能想使用glob:

for  (glob("*.cue")) {
   read_cue($_);
}
Run Code Online (Sandbox Code Playgroud)


Huw*_*ers 5

如果你想过滤 File::Find 递归进入的子目录,你应该使用预处理函数(而不是 $File::Find::prune 变量),因为这给了你更多的控制。这个想法是提供一个函数,每个目录调用一次,并传递文件和子目录的列表;返回值是要传递给所需函数的过滤列表,并且(对于子目录)要递归到其中。

正如 msw 和 Brian 所评论的那样,您的示例可能更适合使用 glob,但如果您想使用 File::Find,您可以执行以下操作。在这里,预处理函数在给定的每个文件或目录上调用 -f,返回文件列表。然后只为这些文件调用想要的函数,并且 File::Find 不会递归到任何子目录:

use strict;
use File::Find;

# Function is called once per directory, with a list of files and
# subdirectories; the return value is the filtered list to pass to
# the wanted function.
sub preprocess { return grep { -f } @_; }

# Function is called once per file or subdirectory.
sub wanted { print "$File::Find::name\n" if /\.cue$/; }

# Find files in or below the current directory.
find { preprocess => \&preprocess, wanted => \&wanted }, '.';
Run Code Online (Sandbox Code Playgroud)

这可用于创建更复杂的文件查找器。例如,我想查找 Java 项目目录中的所有文件,而不是递归到以“.”开头的子目录,例如由 IntelliJ 和 Subversion 创建的“.idea”和“.svn”。您可以通过修改预处理函数来做到这一点:

# Function is called once per directory, with a list of files and
# subdirectories; return value is the filtered list to pass to the
# wanted function.
sub preprocess { return grep { -f or (-d and /^[^.]/) } @_; }
Run Code Online (Sandbox Code Playgroud)

  • prune 变量有什么坏处? (2认同)