Zeile löschen, wenn nächste Zeile gleich ist

15

Welchen sed / awk-Befehl kann ich verwenden? Nur sort -uwerden alle Instanzen entfernt

Eingang:

abc
abc
def
abc
abc
def

Erwartete Ausgabe:

abc
def
abc
def
干 干
quelle

Antworten:

36

Dafür ist der uniqStandardbefehl gedacht.

uniq your-file

Beachten Sie, dass bei einigen uniqImplementierungen wie GNU uniqdie erste Zeile einer Reihe von Zeilen gleich sortiert wird (wobei strcoll()0 zurückgegeben wird) und nicht byteweise identisch ist (wobei memcmp()oder strcmp()0 zurückgegeben wird). Um einen Byte-zu-Byte-Vergleich unabhängig von der uniqImplementierung zu erzwingen, können Sie für das Gebietsschema Folgendes erzwingen C:

LC_ALL=C uniq your-file
Stéphane Chazelas
quelle
7

Vim kann dies gut erreichen:

:g/\v^(.*\n)\1/d

Wenn Sie vim lieber als Befehlszeilentool verwenden möchten, können Sie dies wie folgt tun

vim file -c "g/\v^(.*\n)\1/d" -c "wq"

Auf diese Weise musst du dich später nicht mehr mit dem Verlassen von vim herumschlagen;)

Erläuterung:

:g/

In allen Zeilen, die diesem regulären Ausdruck entsprechen ...

\v^(.*\n)\1

Jede Zeile von selbst gefolgt ...

/d

Führen Sie den Befehl d elete aus (löschen Sie die aktuelle Zeile). Das -c "wq"ist, um die Änderungen zu speichern und zu beenden.

DJMcMayhem
quelle
Beachten Sie, dass mindestens mit Version 8.1.2112 doppelte Zeilen, die die letzten beiden Zeilen der Datei sind, nicht unterstützt werden. Außerdem wird nur ein Duplikat aus Sequenzen von drei Duplikatzeilen entfernt.
Stéphane Chazelas
1
@ StéphaneChazelas mit der Ausnahme, dass wir derzeit keine Spezifikation für das gewünschte Verhalten im 3-Zeilen-Fall haben - ich konnte das gewünschte Verhalten in beide Richtungen sehen.
D. Ben Knoble