2010-09-25 18 views
18

File::Find belgelerinden biraz kafam karışmış ... $ find my_dir -maxdepth 2 -name "*.txt" eşdeğeri nedir?Dosya :: Find Perl'de nasıl kullanabilirim?

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

Ben size aktarmak geri aramalar oluşturmak için kolay hale getirmek için File::Find::Closures yaptı:

+0

'my @files = \' $ bulmak $ my_dir -maxdepth 2 -name * .txt \ ';' ... 'Wanted' altını alamıyorum. Bir regex veremez miyim? –

+0

[Perl ile dosyaları bulma] ile ilgili başka bir soru (http://stackoverflow.com/questions/17754931/finding-files-with-perl), aşağıdaki yanıtlarda belirtilmeyen bazı alternatiflerden bahseder. –

cevap

31

Şahsen, bu geri çağırma yordamları oluşturmanıza gerek olmadığından File::Find::Rule'u kullanmayı tercih ediyorum.

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); 

Veya alternatif bir yineleyici oluşturmak: de kullanışlı find2perl yarar var

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

while (my $file = $ffr_obj->match()) 
{ 
    print "$file\n" 
} 
+0

+1 ile ilgili bulmak çok güzel Bence bu en basit, en' $ find'-like çözüm önerdi. –

+0

ne yazık ki yineleyici ile tüm dizin yapısını belleğe alır. Yapı çok büyük olduğunda (tipik), süreç çok fazla hafıza tüketir. Onun neden bu çözünürlük genellikle iyi değildir. Tersine, sistem tarafından komutunu kullanarak scannind dir ağacı, büyük miktarda RAM tüketmeden çevrim içi olarak getirme seçeneği sunar. – Znik

7

Ben gerçekten tüm dizin geçişi bunlara gerek yok çünkü ben sadece glob kullanmak düşünüyorum 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->(); 

Normalde, (CPAN v5.20 ama kaldırıldı) find2perl ile Perl programa bulunan bir şeyi (1) komutu kapatabilirsiniz:

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

Ama bunu kapalı bırakmak böylece görünüşte find2perl, -maxdepth anlamıyor: sen, bir preprocess aşamayı kapsamaktadır gereken başka türlü başlayan programlama takabilirsiniz olduğunu Şimdi

% 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+"[email protected]"}' 
     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"); 
} 

ağacı kes.

+0

+1 Teşekkürler! 'File :: Find :: Closures' –

6
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" ; 
} 
+0

Teşekkürler - bu sadece aradığım şey. – Winter

2

. Unix find komutunun yerine, 'find' ile aynı komut satırı argümanları yerine kullanın ve File :: Find 'i kullanan karşılık gelen Perl kodunu üretecektir.

İlgili konular