Comment supprimer les lignes en double avec awk tout en gardant les lignes vides?


13

La awkcommande ci-dessous supprime toutes les lignes en double comme expliqué ici :

awk '!seen[$0]++'

Si le texte contient des lignes vides, toutes les lignes vides sauf une seront supprimées.

Comment puis-je conserver toutes les lignes vides tout en supprimant toutes les lignes en double non vides, en utilisant uniquement awk? Veuillez également inclure une brève explication.

Réponses:


28

Une autre option consiste à vérifier NF, par exemple:

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

11

Alternativement

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

L'astuce principale est la même, seen[$0]++crée une entrée dans le seentableau associatif dont la clé est la ligne courante ( $0). Par conséquent, !seen[$0]++sera faux si cette ligne a déjà été vue. Le /./vérifie si la ligne contient des caractères non vides, donc !/./correspond aux lignes non vides. Combiné avec lui, || !seen[$0]++il ignorera toutes les lignes en double sauf les lignes vides et imprimera le reste.


Je pense que cela aurait dû être la réponse acceptée. +1 pour explication!
SS Anne

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

Tout ce que vous avez à faire est de vérifier d'abord une ligne vide (vraiment vide ou juste vide).


5

Voici une autre awksolution, similaire à la réponse de @ Thor, moins concise mais plus efficace:

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

Avec cela, nous vérifions seulement qu'il a[$0]existe ou non. Sinon, initialisez-le puis imprimez. Dans ce cas, nous n'avons aucune référence, affectation à a[$0]si elle existait.


Je n'ai pas mesuré de différence de temps significative avec mon fichier de test de 288 lignes. Cependant, votre code attrape certainement le prix pour être le plus lisible.
Serge Stroobandt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.