bash - else - shell test si chaine contient




Comment pouvez-vous comparer deux pipelines dans Bash? (2)

Comment pouvez-vous diff deux pipelines sans utiliser de fichiers temporaires dans Bash? Supposons que vous ayez deux pipelines de commande:

foo | bar
baz | quux

Et vous voulez trouver le diff dans leurs sorties. Une solution serait évidemment de:

foo | bar > /tmp/a
baz | quux > /tmp/b
diff /tmp/a /tmp/b

Est-il possible de le faire sans l'utilisation de fichiers temporaires dans Bash? Vous pouvez vous débarrasser d'un fichier temporaire en redirigeant l'un des pipelines vers diff:

foo | bar > /tmp/a
baz | quux | diff /tmp/a -

Mais vous ne pouvez pas canaliser simultanément les deux pipelines en diff (pas de manière évidente, au moins). Y a-t-il un truc intelligent impliquant /dev/fd pour faire cela sans utiliser de fichiers temporaires?


Certaines personnes arrivant sur cette page pourraient être à la recherche d'un diff ligne par ligne, pour lequel comm ou grep -f devrait être utilisé à la place.

Une chose à souligner est que, dans tous les exemples de réponses, les différences ne commenceront pas réellement tant que les deux flux n'auront pas été terminés. Testez ceci avec par exemple:

comm -23 <(seq 100 | sort) <(seq 10 20 && sleep 5 && seq 20 30 | sort)

Si c'est un problème, vous pouvez essayer sd (stream diff), qui ne nécessite pas de tri (comme comm ne le fait pas) ni de processus de substitution comme les exemples ci-dessus, est plus rapide que grep -f et prend en charge les flux infinis.

L'exemple de test que je propose serait écrit comme ceci dans sd :

seq 100 | sd 'seq 10 20 && sleep 5 && seq 20 30'

Mais la différence est que seq 100 serait différé avec seq 10 tout de suite. Notez que, si l'un des flux est un tail -f , le diff ne peut pas être effectué avec une substitution de processus.

Voici un article de blogpost j'ai écrit sur diffing streams sur le terminal, qui introduit sd .


Dans bash vous pouvez utiliser des sous-cases, pour exécuter individuellement les pipelines de commande, en entourant le pipeline entre parenthèses. Vous pouvez ensuite les préfixer avec <pour créer des canaux nommés anonymes que vous pouvez ensuite passer à diff.

Par exemple:

diff <(foo | bar) <(baz | quux)

Les pipes nommés anonymes sont gérés par bash afin qu'ils soient créés et détruits automatiquement (contrairement aux fichiers temporaires).





pipeline