2010-02-15 17 views
5

En Perl, se puede obtener una lista de los archivos que coinciden con un patrón:¿Cómo puedo usar el valor de una variable como un patrón glob en Perl?

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

Ahora, me gustaría pasar el patrón como una variable (porque se pasa a una función). Pero eso no funciona:

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

readline() on unopened filehandle at ... 

¿Alguna sugerencia?

Respuesta

12

Uso glob:

use strict; 
use warnings; 

ProcessFiles('*.txt'); 

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

Aquí es una explicación de por qué se obtiene la advertencia, de I/O Operators:

Si lo que los paréntesis angulares contienen es una variable escalar sencilla (por ejemplo, $ foo), entonces esa variable contiene el nombre del identificador de archivo para ingresar de .. . Se considera más limpio para llamar a la función interna directamente como glob ($ foo), que es probablemente la manera correcta de haberlo hecho en el primer lugar.)

-1

¿Qué hay de envolverlo con un comando "eval"? De esta manera ...

+1

Nunca, nunca, nunca, nunca hacer esto . El operador 'glob' es la respuesta correcta. – friedo

+0

Tienes razón, glob es una respuesta mucho mejor. Gracias por la corrección. ¿Por qué "nunca, nunca, nunca, nunca" hacer esto? –

+1

Robert, debes evitar string 'eval' siempre que sea posible; quién sabe qué datos nefastos podrían terminar en '$ pattern', especialmente si eso se deriva de la entrada del usuario. Incluso si no es malicioso, las cosas raras que encuentran su camino en un "eval" pueden ser la causa de muchos errores molestos. – friedo

0

¿Por qué no pasar la referencia de matriz de la lista de archivos a la función?

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

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

Sabía que alguien sugeriría esto. El problema es que en realidad es una variable para empezar, como esta: 'my $ pattern =" test-% d - *. Txt "; ProcessFiles (sprintf ($ patrón, "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" ; 
} 
} 
Cuestiones relacionadas