我需要在第一个目录中编辑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;
}
我尝试了各种
$File::Find::prune = 1;
return;
但没有成功。我应该在哪里放置和定义$File::Find::prune
?
谢谢
答案 0 :(得分:7)
如果您不想递归,可能需要使用glob:
for (glob("*.cue")) {
read_cue($_);
}
答案 1 :(得分:4)
如果要过滤由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 }, '.';
这可用于创建更复杂的文件查找器。例如,我想查找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 /^[^.]/) } @_; }
答案 2 :(得分:1)
如果您只想要目录中的文件而不搜索子目录,则不希望使用File :: Find。一个简单的glob可能就是这个诀窍:
my @files = glob( "$dir_source/*.cue" );
您不需要该子程序。一般来说,当你为一项你认为应该简单的任务做大量的工作时,你可能做错了。 :)
答案 3 :(得分:-1)
假设您有
目录子树/tmp/foo/file.cue /tmp/foo/bar/file.cue /tmp/foo/bar/baz/file.cue
运行
#! /usr/bin/perl
use warnings;
use strict;
use File::Find;
sub read_cue {
if (-f && /\.cue$/) {
print "found $File::Find::name\n";
}
}
@ARGV = (".") unless @ARGV;
find \&read_cue => @ARGV;
输出
found /tmp/foo/file.cue found /tmp/foo/bar/file.cue found /tmp/foo/bar/baz/file.cue
但是如果你还记得你找到cue文件的目录
#! /usr/bin/perl
use warnings;
use strict;
use File::Find;
my %seen_cue;
sub read_cue {
if (-f && /\.cue$/) {
print "found $File::Find::name\n";
++$seen_cue{$File::Find::dir};
}
elsif (-d && $seen_cue{$File::Find::dir}) {
$File::Find::prune = 1;
}
}
@ARGV = (".") unless @ARGV;
find \&read_cue => @ARGV;
你只得到顶级提示文件:
found /tmp/foo/file.cue
这是因为$File::Find::prune
模仿影响目录处理的-prune
find
选项:
-prune
真;如果文件是目录,请不要进入该目录。