2009-11-11 19 views
6

¿Cómo ejecuto un script de Perl en múltiples archivos de entrada con la misma extensión?¿Cómo ejecuto una secuencia de comandos Perl en múltiples archivos de entrada con la misma extensión?

perl scriptname.pl file.aspx 

Busco para que se ejecute para todos los archivos aspx en el directorio actual

Gracias!

+0

Ver http://stackoverflow.com/questions/506009/ scanning-multiple-files-in-perl – daotoad

+0

¿Es posible exportar la salida a un archivo en lugar de tenerlo en el terminal? –

Respuesta

7

En el archivo de Perl,

my @files = <*.aspx>; 
for $file (@files) { 

     # do something. 

} 

El <*.aspx> se llama glob.

+0

Esto funciona, pero solo es necesario si no tiene un shell que hace el trabajo por usted (o el script se inicia mediante un iniciador de interfaz gráfica de usuario, tal vez), y no es tan flexible a pesar de que hace el trabajo. –

+0

Gracias por su comentario. Pero volviendo a leer la pregunta, creo que esta respuesta no necesita calificación. Además, preferiría tener la lógica "obtener todos los archivos con extensión .aspx" dentro del programa en lugar de usar la línea de comando. –

+0

@Jonathan: Es probable que el OP se esté ejecutando en Windows, usando el shell 'cmd'. Por lo que recuerdo, 'cmd' no hace expansión de comodines como lo hacen los shells de Unix. –

1

Si está en una máquina Linux, puede intentar algo como esto.

for i in `ls /tmp/*.aspx`; do perl scriptname.pl $i; done 
+1

uso inútil de ls. - para i in/tmp/* – ghostdog74

+0

En realidad, debe ser './*. aspx' para responder la pregunta. –

+0

Creo que el uso de ls es muy útil para los casos en los que desea procesar los archivos en un orden determinado. Por ejemplo, ls -tr ./*.aspx ejecutará el script Perl en todos los archivos en el orden en que fueron modificados. – Ari

3

puede pasar esos archivos en Perl con comodín

en el script

foreach (@ARGV){ 
    print "file: $_\n"; 
    # open your file here... 
     #..do something 
    # close your file 
} 

en la línea de comandos

$ perl myscript.pl *.aspx 
+3

En Windows, @ARGV tendrá solo un elemento: "* .aspx". – n0rd

-2

También se puede pasar la ruta en la que tenga su archivos aspx y léelos uno por uno.

#!/usr/bin/perl -w 

use strict; 

my $path = shift; 
my @files = split/\n/, `ls *.aspx`; 

foreach my $file (@files) { 
     do something... 
} 
+1

No es necesario que descuelgue a ls, lo que podría no ser un comando válido en algunos sistemas. –

+0

Incluso en sistemas donde 'ls' está disponible, es una herramienta incorrecta para usar aquí, y tiene [múltiples problemas bien documentados] (http://mywiki.wooledge.org/ParsingLs). Perl tiene incorporado globbing tan simplemente 'foreach my $ file (<*.aspx>)' o si sus necesidades son algo más complejas, como esqueleto para el código, 'opendir' el directorio y bucle sobre archivos, haciendo' next a menos que/\.aspx $/'en la parte superior de dentro del ciclo. – tripleee

2

Puede utilizar glob explícitamente, al utilizar parámetros de concha sin depender demasiado en el comportamiento cáscara.

for my $file (map {glob($_)} @ARGV) { 
    print $file, "\n"; 
}; 

Es posible que necesite para controlar la posibilidad de un nombre de archivo duplicado con más de un parámetro ampliado.

0

Para un simple de una sola línea con -n o -p, desea

perl -i~ -pe 's/foo/bar/' *.aspx 

El -i~ dice a modificar cada archivo de destino en su lugar, y dejar el original como una copia de seguridad con un sufijo ~ añadido al archivo nombre. (Omita el sufijo para no dejar una copia de seguridad. Pero si todavía está aprendiendo o experimentando, esa es una mala idea; eliminar las copias de seguridad cuando haya terminado es mucho más pequeño que restaurar los originales desde una copia de seguridad si se estropea algo).)

Si el código Perl es demasiado complejo para una sola línea (o simplemente lo suficientemente útil para ser reutilizables), obviamente, reemplazar -e '# your code here' con scriptname.pl ... aunque entonces tal refactor scriptname.pl para que acepte una lista de argumentos de nombre de archivo, y simplemente use scriptname.pl *.aspx para ejecutarlo en todos los archivos *.aspx en el directorio actual.

Si necesita repetir una estructura de directorio y encontrar todos los archivos con un patrón de nomenclatura particular, la utilidad find es útil.

find . -name '*.aspx' -exec perl -pi~ -e 's/foo/bar/' {} + 

Si su find no soporta -exec ... + intento con -exec ... \; aunque será más lenta y poner en marcha más procesos (uno por cada archivo que encuentre en lugar de la menor cantidad posible de procesar todos los archivos).

para analizar sólo algunos directorios, reemplace . (que da nombre al directorio actual) con una lista separada por espacios de los directorios para examinar, o incluso utilizar find para encontrar los mismos (y tal vez explorar -execdir para hacer algo en directorios cada directorio que find selecciona con su complejo, intrincado, crítico para el negocio, tal vez la lista secreta de find predicados de opción).

Quizás también explore find2perl para hacer esta recursión de directorio nativamente en Perl.

0

Por ejemplo, para manejar perl scriptname.pl *.aspx *.asp

En Linux: El shell expande comodines, por lo que el Perl puede ser simplemente

for (@ARGV) { 
    operation($_); # do something with each file 
} 

de Windows no se expande comodines por lo expanden los comodines en cada argumento en Perl como sigue El bucle procesa cada archivo de la misma manera que el anterior

for (map {glob} @ARGV) { 
    operation($_); # do something with each file 
} 

Por ejemplo, esto va a imprimir la lista ampliada en Windows

print "$_\n" for(map {glob} @ARGV); 
Cuestiones relacionadas