Wie mache ich ein N-Way Diff?

14

Wie kann ich die Ausgabe mehrerer Befehle unterscheiden? vimdiffkann bis zu vier Dateien unterstützen, diffscheint aber genau zwei Dateien zu unterstützen.

Ist es mit irgendeiner Variante von direkt möglich diff, oder muss ich die Ausgabe aller Befehle in temporären Dateien speichern, eine auswählen und den Rest damit vergleichen?


Kontext:

Ich muss die Ausgabe eines bestimmten Befehls auf mehreren Servern überprüfen und prüfen, ob alle übereinstimmen. Im Moment scheint es gut zu sein, nur zu berichten, ob Unterschiede festgestellt wurden, aber wenn möglich, möchte ich sagen können: X% Server stimmen überein, Y% untereinander; oder dieser Server Z ist der ungerade.

Ich habe ein Vier-Wege-Multi-Master-LDAP-Setup und möchte überprüfen, ob die ContextCSNWerte für alle vier miteinander übereinstimmen.

Also mache ich jetzt:

#! /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

Und überprüfen Sie den Fehlercode des Skripts. Gibt es dafür bessere Tools?

Alle Tools, die auf Ubuntu 14.04 verwendet werden können, sind willkommen.

muru
quelle

Antworten:

11

Das Werkzeug dafür ist Diffuse . Es ist auch allgemein bei Repos erhältlich (zumindest in Debian und Arch, wo ich nachgesehen habe). Es funktioniert so, wie Sie es erwarten würden:

  diffuse file1 file2 file3 file4

und so weiter.

MariusMatutiae
quelle
Kann es für die Skripterstellung verwendet werden?
Muru
Ich bekomme eine Reihe von Python GTK Fehlern, und die Man - Page auf Ubuntu 14.04 sagt , es ist ein grafisches Tool, wie auch Debian sid das manpage: manpages.debian.org/cgi-bin/...
muru
Dies sieht aus wie ein wirklich gutes Diff-Tool, das wahrscheinlich von mir selbst verwendet wird. Danke für den Tipp :)
Graeme
6

Das fdupesTool kann Ihnen hier von Nutzen sein (sollte sich in den Repositories befinden). Wenn Sie eine große Anzahl von Dateien zum Vergleichen haben, können Sie diese verwenden, um den Arbeitsaufwand zu verringern, indem Sie ermitteln, welche bereits identisch sind. Wie unten erwähnt, funktioniert es nur mit Verzeichnisargumenten. Wenn Sie alle Dateien in einem Verzeichnis haben, können Sie Folgendes tun:

fdupes .

Identifizieren von Dateien, die gleich sind. Oder:

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

Um Dateien zu identifizieren, die eindeutig sind.

Der diff3Befehl kann auch nützlich sein.

Graeme
quelle
fdupesscheint ein Verzeichnis als Argument zu benötigen (leicht zu umgehen), aber ja, die Anzahl der von zurückgegebenen Dateien fdupesist sehr nützlich.
Muru
@muru, sorry, habe das verpasst. Aktualisiert.
Graeme
5

Wenn Sie nur sehen möchten, ob die Dateien übereinstimmen, brauchen Sie diff nicht wirklich. Einfach benutzen sha1sumoder so ähnlich.

zum Beispiel:

#!/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 

Dadurch erhalten Sie eine durch Leerzeichen getrennte Liste von Server-sha1sum-Paaren. Server mit derselben sha1sum haben dieselbe Ausgabe:

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

Sie können eine weitere Verarbeitung durchführen, um eine Liste der übereinstimmenden Server abzurufen. Beispiel:

#!/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

was gibt Ausgabe wie:

server1 server3 server6
server2 server4
server5
Brian Minton
quelle