Passando due argomenti a un comando usando pipe


22

Di solito, dobbiamo solo passare un argomento:

echo abc | cat
echo abc | cat some_file -
echo abc | cat - some_file

C'è un modo per passare due argomenti? Qualcosa di simile a

{echo abc , echo xyz} | cat
cat `echo abc` `echo xyz`

Prima potrei semplicemente salvare entrambi i risultati in un file

echo abc > file1
echo xyz > file2
cat file1 file2

Ma poi potrei sovrascrivere accidentalmente un file, il che non va bene. Questo sta andando in uno script non interattivo. Fondamentalmente, ho bisogno di un modo per passare i risultati di due comandi arbitrari catsenza scrivere su un file.


AGGIORNAMENTO: Siamo spiacenti, l'esempio maschera il problema. Mentre { echo abc ; echo xyz ; } | catsembra funzionare, l'output è dovuto a echos, non a cat.

Un esempio migliore sarebbe quello { cut -f2 -d, file1; cut -f1 -d, file2; } | paste -d,che non funziona come previsto.

Con

file1:
a,b
c,d

file2:
1,2
3,4

L'output previsto è:

b,1
d,3

DELIBERATO:

Usa la sostituzione del processo :cat <(command1) <(command2)

In alternativa, crea pipe nominate usando mkfifo:

mkfifo temp1
mkfifo temp2
command1 > temp1 &
command2 > temp2 &
cat temp1 temp2

Meno elegante e più dettagliato, ma funziona bene, a patto che tu accerti che temp1 e temp2 non esistano prima.


1
Questo mi fa grattare la testa. Vuoi inoltrare due diversi comandi a un singolo gatto?
user606723

2
Sai che "piping" e "argomenti" sono due concetti completamente indipendenti, giusto?
Ignacio Vazquez-Abrams,

@Ignacio err ... Non ho molta familiarità con Linux, quindi non conosco davvero la differenza. Ho sempre pensato che il piping significasse che prende il risultato precedente come argomento. Vuoi illuminarmi?
Goweon,

@firebat no, pipe significa prendere lo stdout del comando precedente come input standard del comando successivo. Puoi ancora avere argomenti, che sono un concetto diverso.
Rich Homolka,

inoltre, per quanto riguarda il testo di aggiornamento, l'output proviene da cat, solo che le istruzioni sembrano separate da cat, cosa che non può fare poiché sono serializzate in un flusso.
Rich Homolka,

Risposte:


17

Penso che tu voglia 'Sostituzione del processo' http://tldp.org/LDP/abs/html/process-sub.html . Funziona anche su zsh, sebbene abbia più opzioni e la sintassi potrebbe essere diversa.

Crea uno pseudo file ( /dev/fd/something) per ogni sostituzione. È abbastanza utile. Il comando può leggere solo come stream, il che significa che non può andare avanti e indietro con fseek. Deve leggerlo come un flusso di byte, come una pipe.

I tuoi esempi funzionano come sostituzione del processo:

cat <(echo abc) <(echo xyz)
paste -d, <(cut -f2 -d, file1) <(cut -f1 -d, file2)

Pensalo come uno strumento per usare un processo e fingi di essere un file senza alcun file temporaneo.

(dalla mia precedente risposta )


2

Le cose tra parentesi graffe hanno effettivamente funzionato perché l'operatore del tubo collegherà le uscite standard dei comandi raggruppati all'input standard del terzo.

Si può dire che la stampa non proviene dall'eco eseguendo qualsiasi comando che non utilizza l'input standard, ad esempio { echo 1; echo 2;} | echo 3stamperà 3 invece di 1 \ n2 \ n3.

Tuttavia, questa non è la cosa che volevi perché i due comandi tra parentesi graffe stanno scrivendo sullo stesso output che è come fare i catloro risultati. Per generare due risultati diversi da utilizzare come due argomenti per comandi come paste, è necessario utilizzare un file temporaneo o una pipe denominata.

È possibile utilizzare mktempper generare un file temporaneo univoco o mkfifoper creare un file pipe FIFO.


Un grande ringraziamento per la tua risposta, ho cercato molti giorni questa soluzione e finalmente ho trovato la tua risposta qui.
Saeed Falsafin,

2

Mi piacciono gli xargs Come esempio voglio trovare la dimensione di tutti i dir dei dati mysql in / usr / local

osx: utente locale $ pwd
/ Usr / local
osx: utente locale $ ls | grep mysql
mysql
mysql-5.0.51a-osx10.5-x86_64
mysql-5.0.51b-osx10.5-x86_64
mysql-5.1.39-osx10.5-x86_64
mysql-5.6.17-osx10.7-x86_64
os x: utente locale $ ls | grep mysql | sudo xargs du -sh
4.0K mysql
2.8G mysql-5.0.51a-osx10.5-x86_64
 10G mysql-5.0.51b-osx10.5-x86_64
 25G mysql-5.1.39-osx10.5-x86_64
753M mysql-5.6.17-osx10.7-x86_64
osx: utente locale $ 

xargs

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.