Wie entferne ich doppelte Zeilen mit awk, während ich leere Zeilen behalte?


13

Der folgende awkBefehl entfernt alle doppelten Zeilen wie hier erklärt :

awk '!seen[$0]++'

Wenn der Text Leerzeilen enthält, werden alle bis auf eine Leerzeile gelöscht.

Wie kann ich alle leeren Zeilen behalten, während ich alle nicht leeren doppelten Zeilen lösche und nur verwende awk? Bitte fügen Sie auch eine kurze Erklärung bei.

Antworten:


28

Eine andere Möglichkeit ist zu prüfen NF, zB:

awk '!NF || !seen[$0]++'

11

Alternative

awk '!/./ || !seen[$0]++' file

Der Haupttrick ist der gleiche, seen[$0]++erstellt einen Eintrag im seenassoziativen Array, dessen Schlüssel die aktuelle Zeile ( $0) ist. Daher ist !seen[$0]++false, wenn diese Zeile bereits gesehen wurde. Das /./prüft, ob die Zeile irgendwelche nicht leeren Zeichen enthält, also !/./passt es zu nicht leeren Zeilen. In Kombination || !seen[$0]++werden alle doppelten Zeilen mit Ausnahme der leeren ignoriert und der Rest gedruckt.


Ich denke, das hätte die akzeptierte Antwort sein sollen. +1 zur Erklärung!
SS Anne

5
awk '/^[[:blank:]]*$/ { print; next; }; !seen[$0]++'

Alles, was Sie tun müssen, ist, zuerst nach einer leeren (wirklich leeren oder nur leeren) Zeile zu suchen.


5

Hier ist eine andere awkLösung, die der Antwort von @ Thor ähnelt und weniger präzise, ​​aber effizienter ist:

awk '!NF {print;next}; !($0 in a) {a[$0];print}' file

Damit haben wir nur geprüft, ob a[$0]es existiert oder nicht. Wenn nicht, initialisieren Sie es und drucken Sie es aus. In diesem Fall haben wir keinen Bezug, Zuordnung zu, a[$0]falls vorhanden.


Ich habe mit meiner 288-Zeilen-Testdatei keinen signifikanten Zeitunterschied gemessen. Ihr Code wird jedoch mit Sicherheit als der am besten lesbare ausgezeichnet.
Serge Stroobandt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.