Ich habe eine Datei mit zwei Spalten und 10 Millionen Zeilen. Die erste Spalte enthält viele sich wiederholende Werte, aber in Spalte 2 gibt es einen eindeutigen Wert. Ich möchte die sich wiederholenden Zeilen entfernen und nur eine behalten, indem ich awk
. Hinweis: Die Datei ist nach Werten in Spalte 1 sortiert. Beispiel:
1.123 -4.0
2.234 -3.5
2.234 -3.1
2.234 -2.0
4.432 0.0
5.123 +0.2
8.654 +0.5
8.654 +0.8
8.654 +0.9
.
.
.
.
Erwartete Ausgabe
1.123 -4.0
2.234 -3.5
4.432 0.0
5.123 +0.2
8.654 +0.5
.
.
.
.
Antwort1
Einige Möglichkeiten:
awk
awk '!a[$1]++' file
Dies ist eine sehr komprimierte Art, dies zu schreiben:
awk '{if(! a[$1]){print; a[$1]++}}' file
Wenn also das aktuelle erste Feld (
$1
) nicht ima
Array ist, drucken Sie die Zeile und fügen Sie das 1. Feld hinzua
. Wenn wir dieses Feld das nächste Mal sehen, wird es im Array sein und daher nicht gedruckt.Perl
perl -ane '$k{$F[0]}++ or print' file
oder
perl -ane 'print if !$k{$F[0]}++' file
Dies ist im Grunde dasselbe wie das
awk
eine. Das-n
veranlasst Perl, die Eingabedatei Zeile für Zeile zu lesen und das von bereitgestellte Skript-e
auf jede Zeile anzuwenden. Das-a
teilt jede Zeile automatisch bei Leerzeichen auf und speichert die resultierenden Felder im@F
Array. Schließlich wird das erste Feld zum%k
Hash hinzugefügt und wenn es nicht bereits vorhanden ist, wird die Zeile gedruckt. Das Gleiche könnte man auch so schreiben:perl -e 'while(<>){ @F=split(/\s+/); print unless defined($k{$F[0]}); $k{$F[0]}++; }' file
Kerndienstprogramme
rev file | uniq -f 1 | rev
Diese Methode funktioniert, indem zuerst die Zeilen in umgekehrt werden,
file
so dass eine Zeile mit 12 345 nun 543 21 ist. Dannuniq -f 1
ignorieren wir das erste Feld, also die Spalte mit 543. Innerhalb befinden sich Felderfile
. Die Verwendunguniq
von hier hat den Effekt, dass alle doppelten Zeilen herausgefiltert werden und nur jeweils 1 behalten wird. Zuletzt bringen wir die Zeilen mit einer weiteren Umkehrung wieder in ihre ursprüngliche Reihenfolge.GNU sort (alsempfohlenvon @StéphaneChazelas)
sort -buk1,1
Das
-b
Flag ignoriert führende Leerzeichen und-u
bedeutet, dass nur eindeutige Felder gedruckt werden. Der clevere Teil ist das-k1,1
. Das-k
Flag legt das Feld fest, nach dem sortiert werden soll. Es nimmt das allgemeine Format an,-k POS1[,POS2]
was bedeutet, dass beim Sortieren nur die Felder bis POS2 berücksichtigt werdenPOS1
. Also-k1,1
bedeutet, dass nur das 1. Feld berücksichtigt wird. Abhängig von Ihren Daten möchten Sie möglicherweise auch eine dieser Optionen hinzufügen:-g, --general-numeric-sort compare according to general numerical value -n, --numeric-sort compare according to string numerical value
Antwort2
Wenn die erste Spalte immer 5 Zeichen lang ist, können Sie einfach Folgendes verwenden uniq
:
uniq -w 5 file
Wenn nicht, verwenden Sie awk
:
awk '$1!=a{print $0; a=$1}' file
Bei einer großen Datei wäre die erste Methode auf jeden Fall schneller.