Der Befehl uniq filtert oder zählt aufeinanderfolgende doppelte Zeilen in einer Eingabe. Er ist ein klassisches Coreutils-Werkzeug für Log-Analysen, Wordcounts und das Aufspüren von Duplikaten — nahezu immer in Kombination mit sort, denn uniq erkennt nur direkt benachbarte Wiederholungen.

Was uniq macht

uniq liest seine Eingabe zeilenweise und vergleicht jede Zeile nur mit der unmittelbar vorhergehenden. Wiederholungen werden dabei zu einer einzelnen Zeile zusammengefasst. Das hat eine wichtige Konsequenz: Tritt dieselbe Zeile zweimal auf, aber durch andere Zeilen getrennt, sieht uniq keine Duplikate.

Bash uniq ohne sort übersieht Duplikate
printf "apfel\nbirne\napfel\n" | uniq
Output
apfel
birne
apfel

Erst durch vorheriges Sortieren landen Duplikate nebeneinander, und uniq kann sie zusammenfassen. Daraus ergibt sich das klassische Shell-Idiom sort | uniq.

Bash sort | uniq als Idiom
printf "apfel\nbirne\napfel\n" | sort | uniq
Output
apfel
birne

Optionen

OptionWirkung
-c, --countStellt jeder Zeile die Anzahl ihrer Vorkommen voran
-d, --repeatedGibt nur Zeilen aus, die mehrfach vorkommen — pro Gruppe einmal
-D, --all-repeatedGibt alle Vorkommen von Duplikatgruppen aus (nicht reduziert)
-u, --uniqueGibt nur Zeilen aus, die genau einmal vorkommen
-i, --ignore-caseVergleicht case-insensitive
-f N, --skip-fields=NIgnoriert die ersten N Felder beim Vergleich
-s N, --skip-chars=NIgnoriert die ersten N Zeichen beim Vergleich
-w N, --check-chars=NVergleicht nur die ersten N Zeichen jeder Zeile
-z, --zero-terminatedVerwendet NUL statt Zeilenumbruch als Zeilentrenner

Felder werden dabei standardmäßig durch Whitespace getrennt; -f springt zuerst, -s danach.

Idiom sort | uniq -c | sort -rn | head

Eines der nützlichsten Shell-Idiome überhaupt: aus einer beliebigen Liste die häufigsten Einträge ermitteln. Die Pipeline funktioniert in vier Schritten:

  1. sort — bringt gleiche Zeilen nebeneinander
  2. uniq -c — zählt jede Gruppe und stellt die Anzahl voran
  3. sort -rn — sortiert numerisch absteigend nach der Zählung
  4. head — zeigt die Top-N
Bash Top-3 häufigste Frucht
printf "apfel\nbirne\napfel\nkirsche\napfel\nbirne\n" \
    | sort | uniq -c | sort -rn | head -n 3
Output
      3 apfel
      2 birne
      1 kirsche

Dieses Muster taucht in praktisch jeder Log-Analyse auf — IP-Adressen zählen, Status-Codes auswerten, Wortfrequenzen ermitteln.

-d, -u und -D im Vergleich

Die drei Filter-Optionen zeigen unterschiedliche Sichten auf dieselbe Eingabe. Bei sortierter Liste apfel apfel birne kirsche kirsche kirsche ergeben sie:

OptionBedeutungAusgabe (Beispiel)
(kein Flag)Jede Gruppe einmalapfel, birne, kirsche
-dNur Gruppen mit Duplikaten — einmal pro Gruppeapfel, kirsche
-DNur Duplikate — alle Vorkommenapfel, apfel, kirsche, kirsche, kirsche
-uNur Singletonsbirne
Bash -d zeigt Duplikat-Gruppen
printf "apfel\napfel\nbirne\nkirsche\nkirsche\nkirsche\n" | uniq -d
Output
apfel
kirsche
Bash -u zeigt nur einmalige Zeilen
printf "apfel\napfel\nbirne\nkirsche\nkirsche\nkirsche\n" | uniq -u
Output
birne

Felder und Zeichen überspringen

Mit -f N ignoriert uniq die ersten N Felder beim Vergleich, mit -s N die ersten N Zeichen. Praktisch ist das vor allem bei Logs, wo ein wechselnder Timestamp am Zeilenanfang verhindert, dass identische Restzeilen erkannt werden.

Bash -f 1 ignoriert das erste Feld
printf "12:00 login\n12:01 login\n12:02 logout\n" | uniq -f 1 -c
Output
      2 12:00 login
      1 12:02 logout

-s arbeitet zeichengenau und ist nützlich, wenn die Präfixlänge fix ist (z. B. ein 19-stelliger ISO-Timestamp 2026-05-05T12:00:00).

Bash -s 19 überspringt fixen Timestamp
sort access.log | uniq -s 19 -c | sort -rn | head

Praxis

Top-N-Zugriffe in nginx-Logs

Klassische Auswertung: welche IP-Adressen haben am häufigsten zugegriffen?

Bash Top-IPs aus access.log
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head

awk extrahiert das erste Feld (IP), sort gruppiert, uniq -c zählt, sort -rn ordnet absteigend, head schneidet auf die Top 10.

Doppelte Zeilen in einer Datei finden

Bash Duplikate in datei.txt
sort datei.txt | uniq -d

-d gibt jede Duplikat-Gruppe genau einmal aus — ideal für Hash-Listen, E-Mail-Adressen oder Konfigurations-Keys, bei denen du nur wissen willst, welche Werte mehrfach auftauchen, nicht wie oft.

Wordcount-Trick

Mit tr werden Leerzeichen zu Zeilenumbrüchen, danach lässt sich die Wortfrequenz wie gewohnt zählen.

Bash Top-10 Woerter eines Textes
tr -s '[:space:]' '\n' < text.txt | sort | uniq -c | sort -rn | head

tr -s '[:space:]' '\n' faltet jede Whitespace-Folge zu einem einzigen Newline, sodass jede Zeile genau ein Wort enthält. Achtung: Satzzeichen bleiben am Wort kleben — für saubere Wortzählung schaltet man noch ein tr -d '[:punct:]' oder ein tr 'A-Z' 'a-z' davor, je nach Anforderung.

Stolperfallen

uniq ohne sort übersieht Duplikate.

Der wohl häufigste uniq-Bug: ohne vorheriges sort werden nur direkt benachbarte Wiederholungen erkannt. Eine Datei mit apfel, birne, apfel liefert mit uniq drei Zeilen — beide Apfel-Einträge bleiben stehen, weil die Birne dazwischen sitzt. Faustregel: Wer uniq schreibt, schreibt davor fast immer auch sort.

sort -u ist effizienter als sort | uniq.

Wenn du sort und uniq ausschließlich zum Deduplizieren kombinierst, ist sort -u die schlankere und schnellere Variante: das Sortier-Tool entfernt Duplikate direkt während des Sortierens, ohne Pipe und zweiten Prozess. sort | uniq lohnt sich nur dann, wenn du Optionen wie -c, -d oder -D brauchst, die sort -u nicht bietet.

-c braucht zwingend sortierten Input.

uniq -c zählt nur aufeinanderfolgende Gruppen. Bei unsortierter Eingabe entstehen mehrere Teilzählungen pro Wert — apfel taucht dann z. B. zweimal mit jeweils 1 und 2 auf, statt einmal mit 3. Das Ergebnis sieht plausibel aus, ist aber falsch. Vor jeder Frequenz-Auswertung gehört sort davor.

BSD- und GNU-uniq weichen bei -D ab.

Auf macOS (BSD-Userland) und auf Linux (GNU-Coreutils) verhält sich -D nicht identisch. GNU-uniq kennt zusätzlich --all-repeated=METHOD mit Methoden wie prepend oder separate, die Duplikatgruppen mit Leerzeilen trennen können. BSD-uniq versteht diese Form nicht. Wer portable Skripte schreibt, sollte sich auf -c, -d und -u beschränken.

Whitespace-Unterschiede zählen — auch unsichtbare.

uniq vergleicht die rohe Zeile inklusive Trailing-Whitespace und Tabs. Zwei augenscheinlich identische Zeilen, von denen eine mit einem Leerzeichen endet, gelten als unterschiedlich. Wenn die Quelle ungetrimmten Output liefert (z. B. CSV-Exporte aus Tabellenkalkulationen), hilft ein vorgeschaltetes sed 's/[[:space:]]*$//' oder awk '&#123;$1=$1; print&#125;', bevor uniq zum Einsatz kommt.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Textverarbeitung

Zur Übersicht