Perl:如何停止File :: Find递归进入目录?

Ran*_*Rag 2 perl

我正在查看Perl的File::Find模块,并按以下方式尝试:

#!/usr/bin/perl

use warnings;
use strict;

use File::Find;

find({wanted => \&listfiles,
        no_chdir => 1}, ".");


sub listfiles{
    print $File::Find::name,"\n";
}
Run Code Online (Sandbox Code Playgroud)

现在,当我运行它时,我得到以下输出:

Noob@Noob:~/tmp$ perl test.pl 
.
./test.txt
./test.pl
./test1.txt
./hello
./hello/temp.txt
Run Code Online (Sandbox Code Playgroud)

现在,我想通过设置no_chdir=>1我将使我的代码不进入任何目录,如果它遇到一个.但输出清楚地表明我的代码正在进入hello目录并列出其文件.

那么,我如何更改我的代码行为,ls而不是输入任何目录.另外我./在我的文件/目录名称前面可以删除吗?

我正在使用Perl 5.14.

ike*_*ami 15

$File::Find::prune 可用于避免递归到目录.

use File::Find qw( find );

my $root = '.';
find({
   wanted   => sub { listfiles($root); },
   no_chdir => 1,
}, $root);

sub listfiles {
   my ($root) = @_;
   print "$File::Find::name\n";
   $File::Find::prune = 1  # Don't recurse.
      if $File::Find::name ne $root;
}
Run Code Online (Sandbox Code Playgroud)

prune如果您愿意,您可以有条件地设置.

use File::Basename qw( basename );
use File::Find     qw( find );

my %skip = map { $_ => 1 } qw( .git .svn ... );

find({
   wanted   => \&listfiles,
   no_chdir => 1,
}, '.');

sub listfiles {
   if ($skip{basename($File::Find::name)}) {
      $File::Find::prune = 1;
      return;
   }

   print "$File::Find::name\n";
}
Run Code Online (Sandbox Code Playgroud)

no_chdir 没有必要 - 它与你要做的事情无关 - 但我喜欢它做的事情(阻止改变cwd),所以我把它留在了.

  • @ikegami; 不幸的是,这是必要的,因为要报告的第一个节点是要搜索的节点.修剪它将导致只有该目录的列表 (2认同)

Ken*_*sis 12

虽然我认为TLP的建议,请使用glob或者opendir是最适合你的情况下,另一种选择是使用文件::查找::规则 --an接口,用于查找::文件 --with maxdepth(1)停止目录递归:

use Modern::Perl;
use File::Find::Rule;

my $directory = '.';
my @files = File::Find::Rule->maxdepth( 1 )
                            ->file
                            ->name( '*.txt' )
                            ->in( $directory );
say for @files;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只*.txt传递文件名@files.

样本输出:

A.txt
B.txt
columns.txt
data.txt
Run Code Online (Sandbox Code Playgroud)