Ich suche nach einem Befehl, um aus einer Datei in diesem Format zu gelangen:
hello 32
hello 67
hi 2
ho 1212
ho 1390
ho 3000
Zu diesem Format (Deduplizieren durch Nehmen der letzten Zeile einer "Gruppe"):
hello 67
hi 2
ho 3000
Im Moment verwende ich ein Python- und Pandas-Snippet:
df = pd.read_csv(self.input().path, sep='\t', names=('id', 'val'))
# how to replace this logic with shell commands?
surface = df.drop_duplicates(cols=('id'), take_last=True)
with self.output().open('w') as output:
surface.to_csv(output, sep='\t', cols=('id', 'val'))
Update: Danke für die tollen Antworten. Hier einige Benchmarks:
Die Eingabedatei ist 246 MB groß und enthält 8583313 Zeilen. Bestellung spielt keine Rolle. Die erste Spalte hat eine feste Größe von 9 Zeichen.
Beispiel für die Eingabedatei:
000000027 20131017023259.0 00
000000027 20131017023259.0 11
000000035 20130827104320.0 01
000000035 20130827104320.0 04
000000043 20120127083412.0 01
...
time space complexity
tac .. | sort -k1,1 -u 27.43682s O(log(n))
Python/Pandas 11.76063s O(n)
awk '{c[$1]=$0;} END{for(... 11.72060s O(n)
Da die erste Spalte eine feste Länge hat, uniq -w
kann auch verwendet werden:
tac {input} | uniq -w 9 3.25484s O(1)
-w N
berücksichtigt nur die ersten N
Zeichen. Für meine lokale Datei hatte ich also eine 9-Zeichen-ID in der ersten Spalte uniq -w 9
.
uniq -w 5
sollte funktionieren. Ich denke, Ihre und Mikels Antworten sind besser, da sie keine Annahme über die Anzahl der Zeichen in der ersten Spalte machen. Wenn die Eingabe jedoch einer solchen Einschränkung folgt, uniq -w
ist sie die schnellste.
tac {input} | uniq -w 9
funktioniert das?