Passando un argomento a più comandi in una sola riga


10

Mi piacerebbe poter eseguire più comandi sullo stesso file in una sola riga. Il modo in cui lo faccio attualmente è:

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

Il mio istinto mi dice che dovrebbe esserci un modo per fornire l'argomento nomefile solo una volta e reindirizzarlo a entrambi i comandi contemporaneamente attraverso xargso qualcosa di simile:

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

Quando provo questo, viene eseguito solo il primo comando. Come posso ottenere quello che voglio fare?

Risposte:


12

È possibile definire una variabile locale per questo:

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

Puoi anche eseguire tutto incondizionatamente (sostituendo &&con ;) o in parallelo (sostituendo &&con &).

In alternativa, puoi anche usare l'espansione della cronologia della shell per fare riferimento a argomenti precedenti:

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

Non proprio quello che avevo in mente, ma è un'alternativa interessante.
Zaid,

Cosa c'è di sbagliato in questa risposta?
Chris,

Questo è davvero fantastico! Esiste un modo per non definire una nuova variabile?
utente

@utente, ho aggiunto un'alternativa.
Maxschlepzig,

8

Per shell come Bash, Korn e Z che hanno una sostituzione di processo, puoi farlo:

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

2

Puoi usare xargs per costruire una riga di comando, ad esempio:

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

Basta eseguire il pipe di cui sopra in bash per eseguirlo:

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

Estendere l'esempio a tutti i file * .c nella directory corrente (sfuggendo a ls qui per impedire la sostituzione di alias di shell):

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

Utilizzato questo per ottenere un elenco di tutti i file contenuti nelle directory in cui il nome è simile a "enums": find . -name "*enums*" | xargs -i echo -e echo {}\; ls -lh {}\; echo -e '\n\n' | bash
Matt Lachman

1

Non voterei per questo da solo. È sciocco e pericoloso, ma solo nell'interesse di elencare i modi per farlo, c'è:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.