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?

Zaid
fuente

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 && ...
maxschlepzig
fuente
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 '...')
Pausado hasta nuevo aviso.
fuente
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
frielp
fuente
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

precioso
fuente