Pasar dos argumentos a un comando usando tuberías

22

Por lo general, solo necesitamos pasar un argumento:

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

¿Hay alguna manera de pasar dos argumentos? Algo como

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

Podría almacenar ambos resultados en un archivo primero

echo abc > file1
echo xyz > file2
cat file1 file2

Pero luego podría sobrescribir accidentalmente un archivo, lo que no está bien. Esto va en un script no interactivo. Básicamente, necesito una forma de pasar los resultados de dos comandos arbitrarios catsin escribir en un archivo.


ACTUALIZACIÓN: Lo siento, el ejemplo enmascara el problema. Si bien { echo abc ; echo xyz ; } | catparece funcionar, la salida se debe a la echos, no a la cat.

Un mejor ejemplo sería el { cut -f2 -d, file1; cut -f1 -d, file2; } | paste -d,que no funciona como se esperaba.

Con

file1:
a,b
c,d

file2:
1,2
3,4

La salida esperada es:

b,1
d,3

RESUELTO:

Usar sustitución de proceso :cat <(command1) <(command2)

Alternativamente, haga tuberías con nombre usando mkfifo:

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

Menos elegante y más detallado, pero funciona bien, siempre y cuando se asegure de que temp1 y temp2 no existan de antemano.

goweon
fuente
1
Esto me hace rascarme la cabeza. ¿Quieres canalizar dos comandos diferentes a un solo gato?
user606723
2
Sabes que "tubería" y "argumentos" son dos conceptos completamente ajenos, ¿verdad?
Ignacio Vazquez-Abrams
@Ignacio err ... No estoy tan familiarizado con Linux, así que realmente no sé la diferencia. Siempre pensé que tubería significaba que tomaba el resultado anterior como argumento. ¿Te importaría iluminarme?
Goweon
@firebat no, pipe significa tomar el stdout del comando anterior como entrada estándar del siguiente comando. Todavía puede tener argumentos, que son un concepto diferente.
Rich Homolka
Además, en lo que respecta a su texto de actualización, la salida proviene de cat, solo desea que las declaraciones parezcan separadas de cat, lo que no puede hacer ya que están serializadas en una secuencia.
Rich Homolka

Respuestas:

17

Creo que desea 'Proceso de sustitución' http://tldp.org/LDP/abs/html/process-sub.html . También funciona en zsh, aunque tiene más opciones y la sintaxis puede ser diferente.

Crea un pseudo archivo ( /dev/fd/something) para cada sustitución. Es bastante útil El comando solo puede leerse como una secuencia, lo que significa que no puede ir y venir con fseek. Necesita leerlo como una secuencia de bytes, como una tubería.

Sus ejemplos funcionan como sustitución de procesos:

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

Piense en ello como una herramienta para usar un proceso y haga que pretenda ser un archivo sin ningún archivo temporal.

(de mi respuesta anterior )

Rich Homolka
fuente
2

La cosa de llaves realmente funcionó porque el operador de tubería conectará las salidas estándar de los comandos agrupados en la entrada estándar de la tercera.

Puede decir que la impresión no proviene del eco ejecutando cualquier comando que no utilice la entrada estándar, por ejemplo { echo 1; echo 2;} | echo 3, imprimirá 3 en lugar de 1 \ n2 \ n3.

Sin embargo, esto no es lo que deseaba porque los dos comandos en las llaves se escriben en la misma salida, que es similar a catsus resultados. Para generar dos resultados diferentes para usar como los dos argumentos para comandos como paste, deberá usar un archivo temporal o una canalización con nombre.

Puede usarlo mktemppara generar un archivo temporal único o mkfifopara crear un archivo de tubería FIFO.

billc.cn
fuente
Muchas gracias por su respuesta, busqué muchos días para esta solución y finalmente encontré su respuesta aquí.
Saeed Falsafin
2

Me gusta xargs Como ejemplo, quiero encontrar el tamaño de todo el directorio de datos mysql en / usr / local

osx: usuario local $ pwd
/ usr / local
osx: usuario local $ 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: usuario local $ 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: usuario local $ 

xargs

lenguado
fuente