Solution 1 :
Personnellement, mon préféré (nécessite bash et d'autres éléments standard sur la plupart des distributions Linux)
Les détails peuvent dépendre beaucoup de ce que les deux choses sortent et de la façon dont vous voulez 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 génèrent des versions alternatives des mêmes données que vous souhaitez voir côte à côte (j'ai utilisé cela avec snmpwalk ; les numéros 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 (disons 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 (cela pourrait brouiller un peu les choses, cependant) :
cat <(command1 & command2) > outputfile
L'opérateur <() définit un tube nommé (ou /dev/fd) pour chaque commande, en canalisant la sortie de cette commande dans le tube nommé (ou /dev/fd filehandle référence) et transmet le nom sur la ligne de commande. Il y a un équivalent avec>(). Vous pourriez faire :command0 | tee >(command1) >(command2) >(command3) | command4
pour envoyer simultanément la sortie d'une commande à 4 autres commandes, par exemple.
Solution 2 :
Vous pouvez ajouter deux steams à un autre avec cat
, comme le montre le gorille.
Vous pouvez également créer un FIFO, diriger la sortie des commandes vers celui-ci, 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 écrivent ou lisent uniquement un fichier, ou mélangent des programmes qui ne sortent que stdout/file avec un qui ne prend en charge que l'autre.
Solution 3 :
(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.
Solution 4 :
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 stdout ligne par ligne (vous pouvez également remplacer le séparateur)
Solution 5 :
Soyez prudent ici; le simple fait de les cater finira par mélanger les résultats d'une manière que vous ne voudrez 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 d'une ligne de l'autre. Si c'est bon, alors
tail -f /tmp/p1 /tmp/p2>/tmp/sortie
marchera. Si ce n'est pas d'accord, alors vous allez devoir trouver quelque chose qui fera la mise en mémoire tampon de ligne et ne sortira que des lignes complètes. Syslog le fait, mais je ne sais pas quoi d'autre pourrait le faire.
EDIT :optimisation pour la lecture sans tampon et les tubes nommés :
en considérant /tmp/p1 , /tmp/p2 , /tmp/p3 comme des canaux nommés, créés par "mkfifo /tmp/pN "
queue -q -f /tmp/p1 /tmp/p2 | awk '{print $0> "/tmp/p3" ; fermer("/tmp/p3"); fflush();}' &
maintenant de cette façon, nous pouvons lire le canal nommé Output "/tmp/p3" unbuffered par :
tail -f /tmp/p3
il y a un petit bug en quelque sorte, il faut "initialiser" le 1er pipe d'entrée /tmp/p1 par :
echo -n> /tmp/p1
afin de suivre acceptera d'abord l'entrée du 2ème canal /tmp/p2 et n'attendra pas que quelque chose arrive à /tmp/p1 . cela peut ne pas être le cas, si vous êtes sûr, le /tmp/p1 recevra l'entrée en premier.
L'option -q est également nécessaire pour tail n'imprime pas de déchets sur les noms de fichiers.