web-dev-qa-db-fra.com

Passer deux arguments à une commande utilisant des tuyaux

Habituellement, il suffit de passer un argument:

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

Y a-t-il un moyen de passer deux arguments? Quelque chose comme

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

Je pourrais simplement stocker les deux résultats dans un fichier en premier

echo abc > file1
echo xyz > file2
cat file1 file2

Mais alors je pourrais accidentellement écraser un fichier, ce qui n'est pas correct. Cela va dans un script non interactif. Fondamentalement, j'ai besoin d'un moyen de passer les résultats de deux commandes arbitraires à cat sans écrire dans un fichier.


Mise à jour: Désolé, l'exemple masque le problème. Bien que { echo abc ; echo xyz ; } | cat Semble fonctionner, la sortie est due au echos, pas le cat.

Un meilleur exemple serait { cut -f2 -d, file1; cut -f1 -d, file2; } | paste -d, Qui ne fonctionne pas comme prévu.

Avec

file1:
a,b
c,d

file2:
1,2
3,4

La sortie attendue est la suivante:

b,1
d,3

RÉSOLU:

Utilisation substitution de processus : cat <(command1) <(command2)

Alternativement, faites des tuyaux nommés à l'aide de mkfifo:

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

Moins élégant et plus verbeux, mais fonctionne bien, tant que vous vous assurez que TEMP1 et TEMP2 n'existent pas avant la main.

24
goweon

Je pense que vous voulez "substitution de processus" http://tldp.org/ldp/abs/html/process-sub.html . Cela fonctionne également sur ZSH, bien qu'il ait plus d'options et la syntaxe peut être différente.

Cela crée un pseudo fichier (/dev/fd/something) Pour chaque substitution. C'est assez utile. La commande ne peut lire que comme un flux, ce qui signifie qu'il ne peut pas aller d'avant en arrière avec Fsek. Il doit le lire comme un flux d'octets, comme un tuyau.

Vos exemples fonctionnent comme substitution de processus:

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

Pensez-y comme un outil d'utilisation d'un processus et de faire semblant d'être un fichier sans fichiers temporaires.

(de mon réponse antérieure )

17
Rich Homolka

J'aime Xargs comme exemple que je veux trouver la taille de toutes les données MySQL Dir sous/usr/local

[.____] osx: utilisateur local $ pwd [.____]/usr/local 
 OSX: Utilisateur 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: Utilisateur 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: utilisateur local $ [.____]

xargs

2
dab

Les bretelles Curly Thingy ont effectivement fonctionné car l'opérateur de tuyauterie connectera les sorties standard des commandes groupées dans l'entrée standard du troisième.

Vous pouvez dire que l'impression n'est pas des échos en exécutant une commande qui n'utilise pas l'entrée standard, par exemple. { echo 1; echo 2;} | echo 3 Imprimer 3 par opposition à 1\N2\N3.

Cependant, ce n'est pas la chose que vous vouliez car les deux commandes des accessoires bouclés écrivent sur la même sortie qui ressemble à cat-ing de résultats. Pour générer deux résultats différents à utiliser comme les deux arguments pour les commandes telles que paste, vous devez utiliser un fichier temporaire ou un tuyau nommé.

Vous pouvez utiliser mktemp pour générer un fichier temporaire unique ou mkfifo pour créer un fichier FIFO fichier de tuyau.

2
billc.cn