131 votes

Comment supprimer des lignes en double dans un fichier sous Unix?

Existe-t-il un moyen de supprimer les lignes en double dans un fichier sous Unix?

Je peux le faire avec les commandes sort -u et uniq . mais je veux utiliser sed ou awk . Est-ce possible?

283voto

Jonas Elfström Points 16453
awk '!x[$0]++' file.txt

x est associatif-tableau Awk passer chaque ligne du fichier. Si une ligne n'est pas dans le tableau, puis x[$0] sera false. L' ! est un opérateur logique not et inverser le faux pour le vrai. Awk imprimer les lignes où l'expression est évaluée à vrai. L' ++ par incréments de x de sorte qu' x[$0] == 1 après la première fois qu'une ligne est trouvé et puis, x[$0] == 2, et ainsi de suite.
Awk évalue tout, mais 0 et "" (chaîne vide) à true. Si une ligne en double est placé dans x alors !x[$0] évaluera à false et que la ligne ne sera pas écrit dans la sortie.

31voto

Andre Miller Points 6713

De http://sed.sourceforge.net/sed1line.txt : (Veuillez ne pas me demander comment cela fonctionne ;-))

  # delete duplicate, consecutive lines from a file (emulates "uniq").
 # First line in a set of duplicate lines is kept, rest are deleted.
 sed '$!N; /^\(.*\)\n\1$/!P; D'

 # delete duplicate, nonconsecutive lines from a file. Beware not to
 # overflow the buffer size of the hold space, or else use GNU sed.
 sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'
 

6voto

Bradley Kreider Points 694

Le one-liner qui Andre Miller posté ci-dessus fonctionne, sauf pour les versions récentes de sed lorsque le fichier d'entrée se termine par une ligne vide et pas de chars. Sur mon Mac, mon CPU tourne juste.

Boucle infinie si la dernière ligne est vide et n'a pas de caractères:

sed '$!N; /^\(.*\)\n\1$/!P; D'

Ne pas accrocher, mais vous perdez la dernière ligne

sed '$d;N; /^\(.*\)\n\1$/!P; D'

L'explication est à la fin de la sed FAQ:

La GNU sed responsable estimé que malgré les problèmes de portabilité
ce serait la cause, la modification de la N de commande à imprimer (plutôt que de
supprimer) le modèle de l'espace a été plus cohérent avec les intuitions
à propos d'une commande à ajouter la ligne Suivante" devrait se comporter.
Un autre fait en faveur d'un changement était que "{N;commande;}" va
supprimer la dernière ligne si le fichier a un nombre impair de lignes, mais
imprimer la dernière ligne si le fichier a un même nombre de lignes.

Pour convertir les scripts qui a utilisé l'ancien comportement de N (suppression de
le modèle de l'espace, en atteignant la EOF) pour les scripts compatible avec
toutes les versions de sed, changer un seul "N", à "$d;N;".

0voto

Carlos Tasada Points 3629

Il existe un programme Gnome vraiment pratique: FSlint

0voto

pavium Points 7845

sed est un éditeur de flux et ne traite pas naturellement les fichiers d'entrée comme des lignes

C'est peut-être possible, mais je pense que d'autres techniques seront plus faciles.

EDIT: eh bien, la réponse d'Andre Miller montre que ce n'est pas, euh, intuitif

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X