Pasar un argumento a múltiples comandos en una sola línea


10

Me gustaría poder ejecutar múltiples comandos en el mismo archivo en una sola línea. La forma en que hago esto actualmente es:

commandA file && commandB file && perl -ne '...' file

Mi instinto me dice que debería haber una manera de proporcionar el argumento del nombre de archivo solo una vez y canalizarlo a ambos comandos simultáneamente xargso algo similar:

find file | xargs commandA && xargs commandB && xargs perl -ne '...'

Cuando intento esto, solo se ejecuta el primer comando. ¿Cómo puedo lograr lo que quiero hacer?

Respuestas:


12

Puede definir una variable local para esto:

f=file; commandA $f && commandB $f && ...

También puede ejecutar todo incondicionalmente (reemplazando &&con ;) o en paralelo (reemplazando &&con &).

Alternativamente, también puede usar la expansión del historial de shell para hacer referencia a argumentos anteriores:

commandA file && commandB !:1 && ...

No es exactamente lo que tenía en mente, pero es una alternativa interesante.
— Zaid

¿Qué hay de malo en esta respuesta?
— Chris

¡Esto es realmente genial! ¿Hay alguna forma de no definir una nueva variable?
— usuario

@usuario, he agregado una alternativa.
— maxschlepzig

8

Para shells como Bash, Korn y Z que tienen sustitución de proceso, puede hacer esto:

find file | tee >(xargs commandA) >(xargs commandB) >(xargs perl -ne '...')

2

Puede usar xargs para construir una línea de comando, por ejemplo:

echo file | xargs -i -- echo ls -l {}\; wc -l {}

Simplemente conecte lo anterior a bash para ejecutarlo:

echo file | xargs -i -- echo ls -l {}\; wc -l {} | bash

Extendiendo el ejemplo a todos los archivos * .c en el directorio actual (escapando de ls aquí para evitar cualquier sustitución de alias de shell):

\ls -1 *.c | xargs -i -- echo ls -l {}\; wc -l {} | bash

Usé esto para obtener una lista de todos los archivos contenidos en directorios donde el nombre es como "enumeraciones": find . -name "*enums*" | xargs -i echo -e echo {}\; ls -lh {}\; echo -e '\n\n' | bash
— Matt Lachman

1

Yo no votaría por esto yo mismo. Es tonto y peligroso, pero solo por el interés de enumerar las formas de hacer esto, hay:

for cmd in "commandA" "commandB" "perl -ne '...'" ; do eval $cmd file ; done

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.