2010-02-15 8 views
5

In Perl, è possibile ottenere un elenco di file corrispondenti a un modello:Come posso usare il valore di una variabile come modello glob in Perl?

my @list = <*.txt>; 
print "@list"; 

Ora, mi piacerebbe passare il modello come una variabile (perché è passato in una funzione). Ma questo non funziona:

sub ProcessFiles { 
    my ($pattern) = @_; 
    my @list = <$pattern>; 
    print "@list"; 
} 

readline() on unopened filehandle at ... 

Qualche suggerimento?

risposta

12

Uso glob:

use strict; 
use warnings; 

ProcessFiles('*.txt'); 

sub ProcessFiles { 
    my ($pattern) = @_; 
    my @list = glob $pattern; 
    print "@list"; 
} 

Ecco una spiegazione del motivo per cui si ottiene il messaggio di avviso, da I/O Operators:

Se le parentesi angolari contengono è una semplice variabile scalare (ad esempio, $ pippo), quindi quella variabile contiene il nome del filehandle per immettere da .. . È considerato più pulito chiamare la funzione interna direttamente come glob ($ foo), che è probabilmente il modo giusto per averlo fatto in primo luogo.)

-1

Che ne dici di un pacchetto con un comando "eval"? In questo modo ...

sub ProcessFiles { 
    my ($pattern) = @_; 
    my @list; 
    eval "\@list = <$pattern>"; 
    print @list; 
} 
+1

Mai, mai, mai, mai fare questo . L'operatore 'glob' è la risposta corretta. – friedo

+0

Hai ragione, glob è una risposta molto migliore. Grazie per la correzione. Perché mai, mai, mai, mai farlo? –

+1

Robert, dovresti evitare la stringa 'eval' quando possibile; chissà quali dati nefasti potrebbero finire in '$ modello', specialmente se derivano dall'input dell'utente. Anche se non è dannoso, la roba strana che trova la sua via in un 'eval' può essere la causa di molti bug dolorosi. – friedo

0

Perché non passare il riferimento di matrice dell'elenco di file alla funzione?

my @list = <*.txt>; 
ProcessFiles(\@list); 

sub ProcessFiles { 
    my $list_ref = shift; 
    for my $file (@{$list_ref}) { 
     print "$file\n"; 
    } 
} 
+1

Sapevo che qualcuno lo avrebbe suggerito. Il problema è che in realtà è una variabile, come questa: 'my $ pattern =" test-% d - *. Txt "; ProcessFiles (sprintf ($ modello, "51")); ' – Frank

0
use File::Basename; 
@ext=(".jpg",".png",".others"); 
while(<*>){ 
my(undef, undef, $ftype) = fileparse($_, qr/\.[^.]*/); 
if (grep {$_ eq $ftype} @ext) { 
    print "Element '$ftype' found! : $_\n" ; 
} 
}