Comment faire un diff N-way?


14

Comment différencier la sortie de plusieurs commandes? vimdiffpeut prendre en charge jusqu'à quatre fichiers, mais diffsemble prendre en charge exactement deux fichiers.

Est-il directement possible avec une variante de diff, ou dois-je enregistrer la sortie de toutes les commandes dans des fichiers temporaires, en choisir une et en différer le reste avec?


Le contexte:

Je dois vérifier la sortie d'une certaine commande sur plusieurs serveurs et voir s'ils sont tous d'accord. Pour le moment, il suffit de signaler si des différences sont trouvées, mais si possible, j'aimerais pouvoir dire: X% serveurs sont d'accord, Y% les uns avec les autres; ou que le serveur Z est étrange.

J'ai une configuration LDAP multi-maître à quatre voies et je veux vérifier que les ContextCSNvaleurs des quatre sont en accord les unes avec les autres.

Alors maintenant je fais:

#! /bin/bash

for i in {1..4}.ldap 
do 
    ldapsearch -x -LLL -H ldap://$i -s base -b dc=example,dc=com contextCSN > $i.csn; 
done
set -e 
for i in {2..4}
do
    diff -q 1.csn $i.csn
done

Et vérifiez le code d'erreur du script. Existe-t-il de meilleurs outils pour cela?

Tous les outils pouvant être utilisés sur Ubuntu 14.04 sont les bienvenus.

Réponses:


11

L'outil pour ce faire est Diffuse . Il est également généralement disponible à partir des dépôts (au moins dans Debian et Arch, où j'ai vérifié). Cela fonctionne comme vous vous en doutez:

  diffuse file1 file2 file3 file4

etc.


Peut-il être utilisé pour l'écriture de scripts?
muru

Je reçois un tas d'erreurs Python GTK, et la page de manuel sur Ubuntu 14.04 dit que c'est un outil graphique, tout comme la page de manuel de
muru

Cela ressemble à un très bon outil de diff, je vais probablement commencer à l'utiliser moi-même. Merci pour l'astuce :)
Graeme

7

L' fdupesoutil peut vous être utile ici (devrait être dans les référentiels). Si vous avez un grand nombre de fichiers à comparer, vous pouvez l'utiliser pour réduire le travail que vous avez à faire en identifiant ceux qui sont déjà identiques. Comme indiqué ci-dessous, il ne fonctionne qu'avec des arguments de répertoire. Si vous avez tous les fichiers à différencier dans un répertoire, vous pouvez faire quelque chose comme:

fdupes .

Identifier les fichiers identiques. Ou:

comm -13 <(fdupes . |sort -u) <(find . -maxdepth 1 | sort)

Identifier les fichiers uniques.

La diff3commande peut également être utile.


fdupessemble avoir besoin d'un répertoire comme argument (facile à contourner), mais oui, le nombre de fichiers renvoyés par fdupesest très utile.
muru

@muru, désolé, j'ai raté ça. Mis à jour.
Graeme

5

Si vous voulez seulement voir si les fichiers sont d'accord, vous n'avez pas vraiment besoin de diff. Utilisez simplement sha1sumou quelque chose comme ça.

par exemple:

#!/bin/sh
command="foo;bar|baz"
for server in server1 server2 server3 server4 server5 server6: do
    echo $server $(ssh $server "$command" |sha1sum)
done | sort -k2 

Cela vous donnera une liste de paires de serveurs, sha1sum séparées par des espaces. Les serveurs avec le même sha1sum ont la même sortie:

server1 55ca6286e3e4f4fba5d0448333fa99fc5a404a73 *-
server3 55ca6286e3e4f4fba5d0448333fa99fc5a404a73 *-
server6 55ca6286e3e4f4fba5d0448333fa99fc5a404a73 *-
server2 d961c3de6d6c99429806ae3d6d03f316a1168ac6 *-
server4 d961c3de6d6c99429806ae3d6d03f316a1168ac6 *-
server5 dcdc24e139db869eb059c9355c89c382de15b987 *-

Vous pouvez effectuer un traitement supplémentaire pour obtenir une liste de serveurs correspondants, par exemple:

#!/bin/sh
command="foo;bar|baz"
for server in server1 server2 server3 server4 server5: do
    echo $server $(ssh $server "$command" |sha1sum)
done | sort -k2 | while read srv sum; do
    if [ "$prevsum" == "$sum" ]; then 
        echo -n " "
    else
        echo
    fi
    echo -n $srv
    prevsum=$sum
done

ce qui donne une sortie telle que:

server1 server3 server6
server2 server4
server5
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.