Как я могу использовать File :: Find в Perl? - PullRequest
19 голосов
/ 26 сентября 2010

Я немного запутался в документации File::Find ... Что эквивалентно $ find my_dir -maxdepth 2 -name "*.txt"?

Ответы [ 4 ]

31 голосов
/ 27 сентября 2010

Лично я предпочитаю File::Find::Rule, поскольку вам не нужно создавать процедуры обратного вызова.

use strict;
use Data::Dumper;
use File::Find::Rule;

my $dir = shift;
my $level = shift // 2;

my @files = File::Find::Rule->file()
                            ->name("*.txt")
                            ->maxdepth($level)
                            ->in($dir);

print Dumper(\@files);

Или, альтернативно, создать итератор:

my $ffr_obj = File::Find::Rule->file()
                              ->name("*.txt")
                              ->maxdepth($level)
                              ->start($dir);

while (my $file = $ffr_obj->match())
{
    print "$file\n"
}
7 голосов
/ 26 сентября 2010

Думаю, я бы просто использовал glob, так как вам действительно не нужны все вещи для обхода каталога:

 my @files = glob( '*.txt */*.txt' );

Я сделал Файл :: Найти :: Закрытия чтобы вам было проще создавать обратные вызовы, которые вы передаете find:

 use File::Find::Closures qw( find_by_regex );
 use File::Find qw( find );

 my( $wanted, $reporter ) = File::Find::Closures::find_by_regex( qr/\.txt\z/ );

 find( $wanted, @dirs );

 my @files = $reporter->();

Обычно вы можете превратить команду find (1) в программу Perl с помощью find2perl (удалено вv5.20, но на CPAN):

% find2perl my_dir -d 2  -name "*.txt"

Но, очевидно, find2perl не понимает -maxdepth, так что вы можете не указывать:

% find2perl my_dir -name "*.txt"
#! /usr/local/perls/perl-5.13.5/bin/perl5.13.5 -w
    eval 'exec /usr/local/perls/perl-5.13.5/bin/perl5.13.5 -S $0 ${1+"$@"}'
        if 0; #$running_under_some_shell

use strict;
use File::Find ();

# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.

# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

sub wanted;



# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, 'my_dir');
exit;


sub wanted {
    /^.*\.txt\z/s
    && print("$name\n");
}

Теперь, когда у вас естьНачиная программирование, вы можете подключить все, что вам нужно, в том числе шаг preprocess для удаления дерева.

6 голосов
/ 07 декабря 2010
use File::Find ; 
use Cwd ; 

my $currentWorkingDir = getcwd;

my @filesToRun = ();
my $filePattern = '*.cmd' ; 
#add only files of type filePattern recursively from the $currentWorkingDir
find( sub { push @filesToRun, $File::Find::name  
                                    if ( m/^(.*)$filePattern$/ ) }, $currentWorkingDir) ;

foreach  my $file ( @filesToRun  ) 
{
    print "$file\n" ;   
} 
2 голосов
/ 31 октября 2012

Есть также удобная утилита find2perl .Используйте ее вместо команды поиска Unix с теми же аргументами командной строки, что и для 'find', и он сгенерирует соответствующий код Perl, который использует File :: Find.

$ find2perl my_dir -maxdepth 2 -name "*.txt"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...