fuer den Abgleich von Datensaetzen
Zwei CSV-Exporte vergleichen, herausfinden was neu hinzugekommen ist, was fehlt und was gemeinsam ist: sort, uniq und comm loesen diese Aufgabe ohne Datenbank und ohne externe Skriptsprache, allein durch die richtige Kombination dreier klassischer Unix-Werkzeuge.
Inhaltsverzeichnis
- 1. Warum sort, uniq und comm fuer Datenabgleiche unschlagbar sind
- 2. sort richtig einsetzen: Schluessel, Optionen, stabile Sortierung
- 3. uniq fuer Duplikate und Haeufigkeiten: -c, -d, -u
- 4. comm fuer den Zeilen-Abgleich zweier sortierter Dateien
- 5. Kombinierte Pipelines: Diffs zwischen Exporten, Listen, Snapshots
- 6. Grosse Datensaetze: Performance von sort mit --parallel und -T
- 7. Praxisbeispiel: Zwei CSV-Exporte auf Neu, Geloescht und Gemeinsam pruefen
- 8. Fallstricke: Locale, Gross- und Kleinschreibung, Feldtrenner
- 9. Vergleich: comm vs. diff vs. join fuer den Datensatz-Abgleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum sort, uniq und comm fuer Datenabgleiche unschlagbar sind
Der sort uniq comm-Dreiklang gehoert zu den aeltesten Unix-Werkzeugen ueberhaupt und ist trotzdem fuer viele Datenabgleiche noch immer die schnellste Loesung. Der Grund liegt in der klaren Aufgabenteilung: sort bringt Zeilen in eine definierte Reihenfolge, uniq erkennt und reduziert direkt benachbarte Duplikate, und comm vergleicht zwei bereits sortierte Dateien zeilenweise und teilt das Ergebnis in drei Spalten auf, exklusiv fuer Datei eins, exklusiv fuer Datei zwei, und gemeinsame Zeilen.
Anders als eine Datenbank-Abfrage oder ein Skript in einer hoeheren Sprache benoetigt sort uniq comm keine Installation zusaetzlicher Software, keine Zwischenimporte und keine Wartezeit fuer eine Verbindungsherstellung. Die Werkzeuge sind auf praktisch jedem Linux- und Unix-System vorinstalliert und arbeiten streambasiert, was sie fuer Ad-hoc-Abgleiche in Deploy-Skripten und Cronjobs praedestiniert.
Typische Einsatzfelder fuer sort uniq comm sind der Vergleich zweier Nutzerlisten aus unterschiedlichen Systemen, das Erkennen neu hinzugekommener oder entfernter Produkt-IDs zwischen zwei Exporten, oder die Deduplizierung von E-Mail-Adressen aus mehreren Quelldateien. Die folgenden Abschnitte zeigen, wie die drei Werkzeuge einzeln funktionieren und wie sie kombiniert werden, um belastbare Abgleiche zwischen Datensaetzen zu bauen.
2. sort richtig einsetzen: Schluessel, Optionen, stabile Sortierung
Die Grundvoraussetzung fuer jeden sort uniq comm-Abgleich ist eine korrekte Sortierung, denn sowohl uniq als auch comm erwarten bereits sortierte Eingabe und liefern bei unsortierten Daten stillschweigend falsche Ergebnisse, ohne eine Fehlermeldung auszugeben. Die Option -k definiert den Sortierschluessel bei mehrspaltigen Daten, etwa sort -t',' -k2,2 fuer die Sortierung nach der zweiten Spalte einer CSV-Datei mit Komma als Trenner.
Fuer numerische Sortierung ist -n zwingend erforderlich, weil die Standard-Sortierung lexikografisch arbeitet und dabei die Zeichenkette "10" vor "9" einordnen wuerde. Mit -u entfernt sort Duplikate bereits waehrend der Sortierung, was in vielen Faellen den nachgelagerten Aufruf von uniq ueberfluessig macht. Fuer reproduzierbare sort uniq comm-Pipelines in unterschiedlichen Umgebungen sollte zusaetzlich LC_ALL=C gesetzt werden, um Sortierreihenfolgen unabhaengig von der Systemsprache konsistent zu halten.
#!/usr/bin/env bash
set -euo pipefail
# Numeric sort by second column, comma-separated file
LC_ALL=C sort -t',' -k2,2n customers.csv
# Sort and deduplicate in a single pass
LC_ALL=C sort -u email_list_raw.txt > email_list_unique.txt
# Multi-key sort: primary by department, secondary by salary descending
LC_ALL=C sort -t',' -k2,2 -k3,3nr employees.csv
# Stable sort keeps original relative order for equal keys
LC_ALL=C sort -s -t',' -k1,1 export.csv
3. uniq fuer Duplikate und Haeufigkeiten: -c, -d, -u
uniq arbeitet ausschliesslich auf direkt benachbarten Zeilen, weshalb die Kombination mit vorherigem sort fuer sort uniq comm-Aufgaben unerlaesslich ist. Ohne Sortierung erkennt uniq nur Duplikate, die zufaellig bereits nebeneinander in der Datei stehen, alle anderen bleiben unentdeckt. Die Option -c stellt jeder Zeile die Anzahl ihres Vorkommens voran, was fuer Haeufigkeitsanalysen wie "wie oft kommt jede IP-Adresse in diesem Access-Log vor" ideal ist.
Mit -d gibt uniq ausschliesslich Zeilen aus, die mindestens zweimal vorkommen, praktisch fuer das gezielte Aufspueren von Duplikaten in einer eigentlich eindeutigen Liste wie E-Mail-Adressen oder Bestellnummern. Umgekehrt zeigt -u nur Zeilen, die genau einmal vorkommen, was hilfreich ist, um wirklich eindeutige Eintraege von wiederkehrenden zu trennen. Fuer sort uniq comm-Workflows, die auf bestimmte Spalten eingeschraenkt werden sollen, bietet uniq zusaetzlich -f N, um die ersten N Felder beim Vergleich zu ignorieren.
#!/usr/bin/env bash
set -euo pipefail
# Count occurrences per IP address in an access log, sorted by frequency
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20
# Find duplicate email addresses that should be unique
sort emails.txt | uniq -d
# Show only truly unique entries (appearing exactly once)
sort ticket_ids.txt | uniq -u
# Ignore the first field when comparing (e.g. timestamp prefix)
sort logs.txt | uniq -f 1
4. comm fuer den Zeilen-Abgleich zweier sortierter Dateien
Waehrend uniq innerhalb einer einzelnen Datei arbeitet, vergleicht comm zwei separate, jeweils sortierte Dateien Zeile fuer Zeile und teilt das Ergebnis in drei Spalten: Zeilen nur in Datei eins, Zeilen nur in Datei zwei, und Zeilen in beiden Dateien. Genau dieses Verhalten macht sort uniq comm zur idealen Kombination fuer Set-Operationen zwischen zwei Listen, ohne eine Datenbank oder ein komplexeres Tool zu benoetigen.
Mit den Optionen -1, -2 und -3 lassen sich einzelne Spalten gezielt ausblenden. comm -23 datei_a datei_b unterdrueckt Spalte zwei und drei und zeigt nur Zeilen, die ausschliesslich in datei_a vorkommen, waehrend comm -13 datei_a datei_b nur Zeilen zeigt, die ausschliesslich in datei_b stehen. Diese beiden Varianten sind die haeufigsten Anwendungsfaelle von sort uniq comm im Alltag, weil sie direkt beantworten, was zwischen zwei Snapshots hinzugekommen oder entfernt wurde.
#!/usr/bin/env bash
set -euo pipefail
# Prepare sorted, deduplicated files first — mandatory for comm
sort -u yesterday_ids.txt > /tmp/yesterday.sorted.txt
sort -u today_ids.txt > /tmp/today.sorted.txt
# Full three-column output: only in yesterday | only in today | in both
comm /tmp/yesterday.sorted.txt /tmp/today.sorted.txt
# Only new entries (present today, absent yesterday)
comm -23 /tmp/today.sorted.txt /tmp/yesterday.sorted.txt
# Only removed entries (present yesterday, absent today)
comm -23 /tmp/yesterday.sorted.txt /tmp/today.sorted.txt
# Only entries present in both (intersection)
comm -12 /tmp/yesterday.sorted.txt /tmp/today.sorted.txt
5. Kombinierte Pipelines: Diffs zwischen Exporten, Listen, Snapshots
In der Praxis werden sort, uniq und comm selten isoliert eingesetzt, sondern zu Pipelines kombiniert, die mehrere Verarbeitungsschritte in einem einzigen Befehl abbilden. Ein typisches Muster fuer sort uniq comm: Eine Rohdatenquelle wird zunaechst mit awk oder cut auf die relevante Spalte reduziert, dann sortiert und dedupliziert, bevor sie mit einer zweiten, gleich aufbereiteten Datei via comm verglichen wird.
Bei Snapshot-Vergleichen ueber Zeit, etwa taeglichen Exporten einer Produktdatenbank, lohnt es sich, die aufbereiteten Zwischendateien mit einem Zeitstempel zu archivieren, damit spaetere sort uniq comm-Ablaeufe nicht nur den letzten, sondern auch historische Abgleiche zwischen beliebigen zwei Tagen ermoeglichen. Diese Zwischenschicht kostet kaum zusaetzlichen Speicherplatz, weil sortierte, deduplizierte ID-Listen in der Regel deutlich kleiner sind als die Rohdaten, aus denen sie entstanden sind.
6. Grosse Datensaetze: Performance von sort mit --parallel und -T
Bei sehr grossen Dateien im Gigabyte-Bereich wird sort selbst zum Flaschenhals der gesamten sort uniq comm-Pipeline. GNU sort unterstuetzt die Option --parallel=N, um den externen Merge-Sort-Algorithmus auf mehrere CPU-Kerne zu verteilen, was die Sortierzeit auf Mehrkern-Systemen erheblich reduzieren kann. Zusaetzlich steuert -S die Menge an Arbeitsspeicher, die sort vor dem Auslagern auf Festplatte verwenden darf, etwa -S 2G fuer zwei Gigabyte.
Wenn Sortiervorgaenge auf Festplatte ausgelagert werden muessen, weil die Datei nicht komplett in den Arbeitsspeicher passt, legt sort temporaere Dateien an. Mit -T /pfad/zu/schnellem/speicher laesst sich dieses Verzeichnis explizit auf ein schnelles SSD-Volume oder ein tmpfs umlenken, statt den systemweiten Standard unter /tmp zu verwenden, der bei stark ausgelasteten Servern selbst zum Engpass werden kann. Fuer sort uniq comm-Pipelines, die regelmaessig auf grossen Exporten laufen, ist diese Feinabstimmung oft der entscheidende Faktor zwischen einer Laufzeit von Sekunden und mehreren Minuten.
#!/usr/bin/env bash
set -euo pipefail
# Use 4 parallel threads and a fast tmpfs for temporary sort files
sort --parallel=4 -S 2G -T /dev/shm -u huge_export.csv > huge_export.sorted.csv
# Measure the effect of parallel sort on a large file
time sort --parallel=1 huge_export.csv > /dev/null
time sort --parallel=4 huge_export.csv > /dev/null
7. Praxisbeispiel: Zwei CSV-Exporte auf Neu, Geloescht und Gemeinsam pruefen
Ein konkretes Beispiel fuer sort uniq comm im Deploy-Alltag: Zwei taegliche CSV-Exporte eines Produktkatalogs sollen darauf geprueft werden, welche Produkt-IDs neu hinzugekommen sind, welche entfernt wurden, und welche unveraendert in beiden Exporten stehen. Der Ablauf extrahiert zunaechst die ID-Spalte aus beiden Dateien, sortiert und dedupliziert sie, und wendet dann comm mit den passenden Unterdrueckungs-Flags an.
Dieses Muster laesst sich beliebig erweitern, etwa um zusaetzlich die betroffenen Zeilen aus der Originaldatei mit grep -Ff nachzuladen, sodass nicht nur die IDs, sondern die kompletten Datensaetze der neuen oder entfernten Eintraege ausgegeben werden. So entsteht aus drei einfachen sort uniq comm-Kommandos ein vollstaendiger, automatisierbarer Report fuer Produktkatalog-Aenderungen.
#!/usr/bin/env bash
set -euo pipefail
# Extract, sort and deduplicate product IDs from both exports
awk -F',' 'NR>1{print $1}' export_yesterday.csv | sort -u > /tmp/ids_yesterday.txt
awk -F',' 'NR>1{print $1}' export_today.csv | sort -u > /tmp/ids_today.txt
echo "New product IDs:"
comm -23 /tmp/ids_today.txt /tmp/ids_yesterday.txt
echo "Removed product IDs:"
comm -23 /tmp/ids_yesterday.txt /tmp/ids_today.txt
echo "Unchanged product IDs (present in both):"
comm -12 /tmp/ids_yesterday.txt /tmp/ids_today.txt | wc -l
# Fetch full rows for the new IDs from the current export
grep -Ff <(comm -23 /tmp/ids_today.txt /tmp/ids_yesterday.txt) export_today.csv
8. Fallstricke: Locale, Gross- und Kleinschreibung, Feldtrenner
Der haeufigste Fehler bei sort uniq comm-Abgleichen ist eine inkonsistente Locale zwischen den beteiligten Sortieraufrufen. Ohne LC_ALL=C nutzt sort die systemweite Locale, die Umlaute, Gross- und Kleinschreibung sowie Sonderzeichen anders einordnet als eine reine Byte-Sortierung. Wird eine Datei mit einer anderen Locale sortiert als die zweite, liefert comm scheinbar falsche Ergebnisse, weil die vermeintlich sortierte Reihenfolge tatsaechlich nicht identisch ist.
Ein zweiter Fallstrick betrifft Gross- und Kleinschreibung: sort behandelt "Apfel" und "apfel" standardmaessig als unterschiedliche Zeichenketten, was bei sort uniq comm-Abgleichen von Namen oder E-Mail-Adressen zu unerwarteten Ergebnissen fuehren kann, wenn dieselbe Adresse einmal in Klein- und einmal in Grossschreibung vorkommt. Die Option -f bei sort ignoriert Gross- und Kleinschreibung beim Sortieren, wobei uniq separat mit der eigenen -i-Option ebenfalls case-insensitive Duplikate erkennen kann. Beim dritten Fallstrick, unterschiedlichen Feldtrennern zwischen zwei CSV-Dateien, sollte vor jedem Abgleich geprueft werden, dass beide Quellen tatsaechlich denselben Trenner und dieselbe Spaltenreihenfolge verwenden, sonst vergleicht comm Werte, die inhaltlich gar nicht zusammengehoeren.
9. Vergleich: comm vs. diff vs. join fuer den Datensatz-Abgleich
Neben sort uniq comm gibt es mit diff und join zwei weitere Standardwerkzeuge, die auf den ersten Blick aehnliche Aufgaben loesen, sich aber in wichtigen Details unterscheiden.
| Aufgabe | comm | diff | join |
|---|---|---|---|
| Mengenvergleich zweier Listen | Ideal, drei Spalten direkt | Erfordert Nachbearbeitung | Ungeeignet ohne gemeinsamen Schluessel |
| Voraussetzung Eingabe | Muss sortiert sein | Beliebige Reihenfolge | Muss sortiert sein |
| Zeilenweise Textaenderungen | Nicht vorgesehen | Klassischer Anwendungsfall | Nicht vorgesehen |
| Zusaetzliche Spalten pro Schluessel kombinieren | Nicht moeglich | Nicht moeglich | Genau dafuer gebaut |
| Reine Existenzpruefung (in A, aber nicht B) | comm -23 |
Umstaendlicher | Machbar mit -v |
Fuer reine Set-Operationen zwischen zwei sortierten Listen bleibt sort uniq comm die direkteste Loesung, weil das Ergebnis sofort in drei klar getrennte Spalten aufgeteilt wird. diff ist dagegen die richtige Wahl, wenn tatsaechliche Textaenderungen innerhalb von Zeilen interessieren, etwa bei Config-Dateien oder Quellcode. join wiederum spielt seine Staerken aus, sobald zu einem gemeinsamen Schluessel zusaetzliche Spalten aus beiden Dateien kombiniert werden sollen, aehnlich einem SQL-Join.
Mironsoft
Datenabgleiche, Export-Vergleiche und Automatisierung in der Shell
Manuelle Excel-Abgleiche durch verlaessliche Skripte ersetzen?
Wir bauen Abgleich-Skripte fuer wiederkehrende Exporte, Produktkataloge und Nutzerlisten, die zuverlaessig, nachvollziehbar und automatisierbar sind, ganz ohne zusaetzliche Software.
Abgleich-Skripte
Massgeschneiderte sort/uniq/comm-Pipelines fuer eure Datenquellen
Automatisierung
Taegliche Abgleiche als Cronjob mit Reporting einrichten
Performance-Tuning
sort mit --parallel und -T fuer grosse Exporte optimieren
10. Zusammenfassung
Sort uniq comm bilden zusammen eine schlanke, ueberall verfuegbare Loesung fuer den Abgleich zweier Datensaetze, ohne Datenbank und ohne zusaetzliche Software. sort stellt die zwingende Voraussetzung fuer sortierte Eingabe her, uniq erkennt Duplikate und Haeufigkeiten innerhalb einer Datei, und comm vergleicht zwei sortierte Dateien Zeile fuer Zeile und liefert das Ergebnis direkt in drei klar getrennten Spalten.
Fuer verlaessliche Ergebnisse ist eine konsistente Locale mit LC_ALL=C ueber alle beteiligten Sortieraufrufe hinweg entscheidend, ebenso wie ein einheitlicher Feldtrenner zwischen den zu vergleichenden Dateien. Bei sehr grossen Datensaetzen sorgen --parallel und -T fuer deutlich kuerzere Laufzeiten. Fuer reine Mengenvergleiche bleibt sort uniq comm die direkteste Loesung, waehrend diff bei Textaenderungen und join bei spaltenweisen Verknuepfungen die bessere Wahl sind.
Sort, uniq und comm fuer den Datensatz-Abgleich: Das Wichtigste auf einen Blick
sort als Voraussetzung
Beide Dateien muessen sortiert sein, bevor uniq oder comm sinnvolle Ergebnisse liefern. LC_ALL=C sichert konsistente Reihenfolge.
uniq -c / -d / -u
-c zaehlt Vorkommen, -d zeigt nur Duplikate, -u zeigt nur eindeutige Zeilen einer sortierten Datei.
comm -23 / -13 / -12
Drei Spalten steuerbar: nur Datei eins, nur Datei zwei, oder nur gemeinsame Zeilen.
Performance
sort --parallel=N und -T /schneller/pfad beschleunigen die Sortierung grosser Exporte deutlich.