MWCodebymw.de ↗
Terminal

Zwei Listen vergleichen mit comm – wer fehlt, wer ist neu, wer ist in beiden

Welche Dateien fehlen im Backup? Welche Kunden aus der alten Liste stehen nicht in der neuen? Für genau diese Fragen gibt es seit Unix-Urzeiten ein Werkzeug, das kaum jemand kennt – comm vergleicht zwei sortierte Listen und sagt dir in einer Zeile, was nur links, nur rechts oder in beiden steht.

Die Aufgabe taucht ständig auf, nur in wechselnden Kostümen: zwei Listen, und du willst wissen, worin sie sich unterscheiden. Die Dateien auf dem Server gegen die im Backup. Die E-Mail-Adressen von letztem Monat gegen die von heute. Die Pakete auf Rechner A gegen die auf Rechner B.

Der Reflex ist oft eine Schleife mit grep – langsam und umständlich. diff wiederum erzählt dir, *wie* man Datei A in Datei B umbaut, das ist für Listen mehr, als du wissen willst. Das richtige Werkzeug heißt comm, ist Teil der GNU Coreutils und damit überall schon installiert.

Drei Spalten, drei Antworten

comm vergleicht zwei sortierte Dateien Zeile für Zeile und gibt drei Spalten aus: Zeilen nur in der ersten Datei, Zeilen nur in der zweiten, Zeilen in beiden.

$ cat alt.txt          $ cat neu.txt
anna@example.de        anna@example.de
bernd@example.de       clara@example.de
clara@example.de       doris@example.de

$ comm alt.txt neu.txt
		anna@example.de
bernd@example.de
		clara@example.de
	doris@example.de

Spannend wird es mit den Schaltern: Sie unterdrücken Spalten, statt sie auszuwählen. -1 blendet Spalte 1 aus, -2 Spalte 2, -3 Spalte 3 – und kombiniert ergeben sich die drei Fragen des Alltags:

comm -23 alt.txt neu.txt   # nur in ALT: wer ist rausgeflogen?
comm -13 alt.txt neu.txt   # nur in NEU: wer ist dazugekommen?
comm -12 alt.txt neu.txt   # in BEIDEN: die Schnittmenge

Merken kannst du es dir so: Die Ziffern nennen, was weg soll. -23 heißt „Spalte 2 und 3 weg" – übrig bleibt, was nur links steht.

Die eine Falle: Sortierung

comm verlangt, dass beide Listen gleich sortiert sind – sonst meldet es file is not in sorted order oder liefert stillschweigend Unsinn. Sortiere deshalb beide Seiten mit demselben sort, am besten direkt in der Kommandozeile per Prozess-Substitution:

comm -13 <(sort -u alt.txt) <(sort -u neu.txt)

-u wirft dabei Dubletten raus. Wichtig auf verschiedenen Systemen: Die Sortierreihenfolge hängt an der Locale. Wenn eine Liste vom Server kommt und eine vom Laptop, zwinge beide auf dieselbe Ordnung:

comm -13 <(LC_ALL=C sort alt.txt) <(LC_ALL=C sort neu.txt)

Ein echtes Beispiel: Backup-Abgleich

So prüfe ich, ob ein Backup wirklich alles hat – zwei Dateilisten, eine Frage:

comm -23 <(cd /var/www && find . -type f | LC_ALL=C sort) \
         <(cd /backup/www && find . -type f | LC_ALL=C sort)

Jede ausgegebene Zeile ist eine Datei, die auf dem Server existiert, aber im Backup fehlt. Keine Ausgabe, keine Lücke – und das Ganze läuft auch über zehntausende Zeilen in einem Wimpernschlag.

Solche kleinen Bausteine stecken in fast jedem meiner Deploy- und Wartungs-Skripte. Wenn du für dein Projekt eine Website mit sauberem Unterbau willst, bei dem solche Prüfungen einfach mitlaufen: Auf bymw.de zeige ich, wie ich arbeite.

Quellen

#comm#sort#Listen#Terminal

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →