2009-01-22 13 views
6

Según tengo entendido (Perl es nuevo para mí), Perl se puede utilizar para crear scripts frente a una línea de comandos de Unix. Lo que quiero hacer es ejecutar llamadas de línea de comandos (codificadas) y buscar en las salidas de estas llamadas para las coincidencias de RegEx. ¿Hay alguna manera de hacer esto simplemente en Perl? ¿Cómo?¿Cómo uso Perl en la línea de comando para buscar el resultado de otros programas?

EDITAR: La secuencia aquí es: -Extraiga otro programa. -Ejecuta un regex contra su salida.

Respuesta

10
my $command = "ls -l /"; 
my @output = `$command`; 
for (@output) { 
    print if /^d/; 
} 

El qx//-cuasi citando operador (por que acentos abiertos son un acceso directo) es robado de sintaxis shell: ejecutar la cadena como un comando en un nuevo shell, y devolver su salida (como una cadena o una lista, dependiendo del contexto). Vea perlop para más detalles.

También puede abrir una tubería:

open my $pipe, "$command |"; 
while (<$pipe>) { 
    # do stuff 
} 
close $pipe; 

Esto le permite (a) evitar la recolección de la producción de todo el comando en memoria a la vez, y (b) le da un mayor control sobre la ejecución del comando. Por ejemplo, se puede evitar que el comando de ser analizada por el shell:

open my $pipe, '-|', @command, '< single argument not mangled by shell >'; 

Ver perlipc para más detalles al respecto.

+0

O como terminé implementándolo: for (@output) { my_action() if/regex /; } Permitiéndome hacer lo que quiera si recibo un golpe. ¡Gracias! – alexwood

2
#!/usr/bin/perl 

sub my_action() { 
     print "Implement some action here\n"; 
} 

open PROG, "/path/to/your/command|" or die $!; 
while (<PROG>) { 
     /your_regexp_here/ and my_action(); 
     print $_; 
} 
close PROG; 

Esto escaneará salida de su mando, las expresiones regulares de los partidos y hacer algo de acción (que ahora se está imprimiendo la línea)

+0

quizás sería mejor reemplazar la instrucción de impresión con un bloque do. – Geo

+0

Esto no ejecuta ninguna de las "llamadas de línea de comando (codificadas)" deseadas, simplemente lee y actúa sobre la entrada estándar. – ephemient

2

¿Necesita Perl en absoluto? ¿Qué hay de

command -I use | grep "myregexp" && dosomething 

¿derecho en el caparazón?

+0

Esto va a suceder cientos de veces, y voy a agregar un archivo de salida, así que sí. Pero su orden es bastante similar a la que disparará Perl: P – alexwood

+0

para el archivo de salida, "empate". Pero cientos de veces ... Puede ser Perl. – Arkadiy

2

En Perl puede usar los trazos para ejecutar comandos en el shell. Aquí hay un document on using backticks. No estoy seguro acerca de cómo capturar la salida, pero estoy seguro de que hay más que una forma de hacerlo.

4

Es posible que pueda alejarse sin Perl, como han mencionado otros. Sin embargo, si hay alguna característica de Perl que necesita, como funciones de expresiones regulares extendidas o manipulación de texto adicional, puede canalizar su salida a perl y luego hacer lo que necesita. de Perl -e conmutador de que especifique el programa de Perl en la línea de comando let:

command | perl -ne 'print if /.../' 

Hay varios otros modificadores que puede pasar a perl para que sea muy potente en la línea de comandos. Estos están documentados en perlrun. También puedes ver algunos de los artículos en Randal Schwartz's Unix Review column, especialmente su first article for them. También puede buscar en google Perl one liners para encontrar muchos ejemplos.

+0

¿No ha omitido la bandera -n aquí? – reinierpost

0

De hecho, utiliza una línea en un caso como este.

Recientemente he codificado un pequeño modulino que utilizo, entre otras formas, para producir resultados que enumeren la estructura de directorios presente en un archivo .zip (una entrada dir por línea).Entonces, usando ese resultado como un ejemplo de salida de comando que nos gustaría filtrar, podríamos poner un conducto y luego usar perl con los indicadores -n -e para filtrar los datos entrantes (y/o hacer otras cosas con él):

[command_producing_text_output] | perl -MFile::Path -n -e \ 
    "BEGIN{@PTM=()} if (m{^perl/(bin|lib(?!/site))}) {chomp;push @PTM,$_}"^
-e "END{@WDD=mkpath (\@PTM,1);"^
-e "printf qq/Created %u dirs to reflect part of structure present in the .ZIP file\n/, scalar(@WDD);}" 

la sintaxis del intérprete de comandos utilizada, que incluye: citar el código perl y el escape de nuevas líneas, refleja el uso de CMD.exe en consolas similares a Windows NT. Si es necesario, mentalmente sustituir "^" con "\" y "con" en los lugares apropiados.

La sola línea anterior agrega sólo los nombres de directorio que comienzan con 'perl/bin' o " perl/lib (no seguido de "/ sitio"); luego crea esos directorios. Dirige con un árbol (vacío) que puede usar para cualquier propósito malvado que desee.

El punto principal es ilustrar que hay banderas disponibles (-n, -p) a permiten Perl para recorrer cada registro de entrada (línea), y que lo que puede hacer es ilimitada en términos de complejidad.

Cuestiones relacionadas