Gibt es eine bessere Lösung für das Drucken eindeutiger Zeilen als eine Kombination aus sort
und uniq
?
Gibt es eine bessere Lösung für das Drucken eindeutiger Zeilen als eine Kombination aus sort
und uniq
?
Antworten:
So drucken Sie für jede identische Zeile nur eine Zeile in beliebiger Reihenfolge:
sort -u
So drucken Sie nur die eindeutigen Zeilen in beliebiger Reihenfolge:
sort | uniq -u
So drucken Sie jede identische Zeile nur einmal in der Reihenfolge ihres ersten Auftretens: (Drucken Sie für jede Zeile die Zeile, wenn sie noch nicht gesehen wurde, und erhöhen Sie in jedem Fall den Zähler für gesehene Zeilen.)
awk '!seen[$0] {print}
{++seen[$0]}'
So drucken Sie nur die eindeutigen Zeilen in der Reihenfolge ihres ersten Auftretens: (Zeichnen Sie jede Zeile in seen
und auch in der Reihenfolge ihres ersten Auftretens auf lines
; drucken Sie am Ende der Eingabe die Zeilen in der Reihenfolge ihres Auftretens, jedoch nur die angezeigten Zeilen Einmal)
awk '!seen[$0]++ {lines[i++]=$0}
END {for (i in lines) if (seen[lines[i]]==1) print lines[i]}'
awk '!seen[$0]++ {print}'
?
awk '!seen[$0]++'
, da das {print}
durch einen leeren Befehl impliziert wird.
Einige (die meisten?) Versionen von sort
haben ein -u
Flag, das den uniq
Teil direkt erledigt . Abhängig von der Implementierung kann es jedoch zu Einschränkungen der Zeilenlänge kommen, die Sie jedoch bereits mit plain hatten sort|uniq
.
sort -u
geht zumindest auf V7 zurück.
-u
jedoch auch eine Zeilenlängenbeschränkung von 512 Zeichen. (Eigentlich glaube ich, dass Solaris 9 Sun es auf 5120 erhöht hat. GNU gewinnt jedoch immer noch.)
Funktioniert Perl für Sie? Es kann die Zeilen in der ursprünglichen Reihenfolge beibehalten, auch wenn die Duplikate nicht benachbart sind. Sie können es auch in Python codieren oder awk
.
while (<>) {
print if $lines{$_}++ == 0;
}
Welches kann nur gekürzt werden
perl -ne 'print unless $lines{$_}++;'
Gegebene Eingabedatei:
abc
def
abc
ghi
abc
def
abc
ghi
jkl
Es ergibt die Ausgabe:
abc
def
ghi
jkl
use strict;
oder gibt use warnings;
(eigentlich ist es das strict
, was hier am relevantesten ist), gibt es keine Beschwerde über die Verwendung, %lines
bevor es definiert ist. Wenn mit Einschränkungen gearbeitet wird, muss my %lines;
vor der Schleife eine Linie stehen . Beachten Sie auch, dass der Hash ist %lines
; Ein Element des Hash wird mit der $lines{$_}
Notation referenziert .
sort
Lösungen sind möglicherweise besser für große Datenmengen (das OP war besorgt über das "Speichern der gesamten Datei im Speicher"). sort
führt eine Out-of-Core-Sortierung durch, wenn die Daten größer als der verfügbare Speicher sind.
Für den letzten Teil der Antwort unter: Drucken eindeutiger Zeilen durch @Gilles als Antwort auf diese Frage habe ich versucht, die Verwendung von zwei Hashes zu vermeiden.
Diese Lösung ist für folgende Zwecke vorgesehen: So drucken Sie nur die eindeutigen Zeilen in der Reihenfolge ihres ersten Auftretens:
awk '{counter[$0]++}
END {for (line in counter) if (counter[line]==1) print line}'
Hier speichert "counter" eine Zählung jeder Zeile, die der zuvor verarbeiteten ähnlich ist.
Am Ende werden nur die Zeilen gedruckt, deren Zählerwert 1 ist.