Utilisation des tuyaux (|
) dans Linux, je peux transmettre en chaîne l'entrée standard à un ou plusieurs flux de sortie.
Je peux utiliser tee
pour diviser la sortie en sous-processus séparés.
Existe-t-il une commande pour joindre deux flux d'entrée?
Comment pourrais-je m'y prendre? Comment fonctionne diff?
Personnellement, mon préféré (nécessite bash et d'autres choses standard sur la plupart des distributions Linux)
Les détails peuvent dépendre en grande partie de la sortie des deux éléments et de la manière dont vous souhaitez les fusionner ...
Contenu de command1 et command2 l'un après l'autre dans la sortie:
cat <(command1) <(command2) > outputfile
Ou si les deux commandes produisent des versions alternatives des mêmes données que vous souhaitez voir côte à côte (je l'ai utilisé avec snmpwalk; les nombres d'un côté et les noms MIB de l'autre):
paste <(command1) <(command2) > outputfile
Ou si vous voulez comparer la sortie de deux commandes similaires (dites une recherche sur deux répertoires différents)
diff <(command1) <(command2) > outputfile
Ou s'il s'agit de sorties ordonnées, fusionnez-les:
sort -m <(command1) <(command2) > outputfile
Ou exécutez les deux commandes à la fois (pourrait brouiller un peu les choses, cependant):
cat <(command1 & command2) > outputfile
L'opérateur <() configure un canal nommé (ou/dev/fd) pour chaque commande, en canalisant la sortie de cette commande dans le canal nommé (ou/dev/fd référence de descripteur de fichier) et transmet le nom sur la ligne de commande. Il y a un équivalent avec> (). Vous pouvez faire: command0 | tee >(command1) >(command2) >(command3) | command4
pour envoyer simultanément la sortie d'une commande à 4 autres commandes, par exemple.
Vous pouvez ajouter deux vapeurs à l'autre avec cat
, comme le montre le gorille.
Vous pouvez également créer un FIFO, diriger la sortie des commandes vers cela, puis lire à partir du FIFO avec n'importe quel autre programme:
mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo
Particulièrement utile pour les programmes qui n'écriront ou ne liront qu'un fichier, ou pour mélanger des programmes qui ne produisent que stdout/file avec un qui ne prend en charge que l'autre.
(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output
/tmp/p1
et /tmp/p2
sont vos canaux d'entrée, tandis que /tmp/output
est la sortie.
J'ai créé un programme spécial pour cela: fdlinecombine
Il lit plusieurs canaux (généralement des sorties de programme) et les écrit dans la sortie standard de la ligne (vous pouvez également remplacer le séparateur)
Faites attention ici; le simple fait de les attacher finira par mélanger les résultats comme vous ne le souhaitez peut-être pas: par exemple, s'il s'agit de fichiers journaux, vous ne voulez probablement pas vraiment qu'une ligne de l'un soit insérée à mi-chemin à travers une ligne de l'autre. Si ça va, alors
tail -f/tmp/p1/tmp/p2>/tmp/sortie
marchera. Si c'est pas d'accord, alors vous devrez trouver quelque chose qui fera la mise en mémoire tampon des lignes et ne produira que des lignes complètes. Syslog fait cela, mais je ne sais pas quoi d'autre pourrait le faire.
EDIT: optimisation pour la lecture sans tampon et les canaux nommés:
considérant/tmp/p1,/tmp/p2,/tmp/p3 comme des canaux nommés, créés par "mkfifo/tmp/p [~ # ~] n [~ # ~] "
queue -q -f/tmp/p1/tmp/p2 | awk '{print $ 0> "/ tmp/p3"; fermer ("/ tmp/p3"); fflush ();} '&
maintenant de cette façon, nous pouvons lire la sortie nommée pipe "/ tmp/p3" sans tampon par:
queue -f/tmp/p3
il y a un petit bug en quelque sorte, il faut "initialiser" le 1er pipe d'entrée/tmp/p1 en:
echo -n>/tmp/p1
afin de tail acceptera d'abord l'entrée du 2ème tube/tmp/p2 et n'attendra pas que quelque chose arrive à/tmp/p1. ce n'est peut-être pas le cas, si vous êtes sûr, le/tmp/p1 recevra d'abord l'entrée.
L'option -q est également nécessaire pour que tail n'imprime pas les ordures sur les noms de fichiers.
Une commande vraiment cool que j'ai utilisée pour cela est tpipe
, vous pourriez avoir besoin de compiler car ce n'est pas si courant. C'est vraiment génial pour faire exactement ce dont vous parlez, et c'est tellement propre que je l'installe habituellement. La page de manuel se trouve ici http://linux.die.net/man/1/tpipe . Le téléchargement actuellement répertorié se trouve dans cette archive http://www.eurogaran.com/downloads/tpipe/ .
Il est utilisé comme ça,
## Reinject sub-pipeline stdout into standard output:
$ pipeline1 | tpipe "pipeline2" | pipeline3
Le meilleur programme pour ce faire est lmerge
. Contrairement à la réponse de freihart, elle est orientée ligne, de sorte que la sortie des deux commandes ne s'encombrera pas. Contrairement à d'autres solutions, il fusionne assez bien l'entrée afin qu'aucune commande ne puisse dominer la sortie. Par exemple:
$ lmerge <(yes foo) <(yes bar) | head -n 4
Donne la sortie de:
foo
bar
foo
bar