Existe-t-il une meilleure solution pour imprimer des lignes uniques autres qu'une combinaison de sort
et uniq
?
command-line
text-processing
Laisse-moi tranquille
la source
la source
sort
(par exemple GNU coreutils) utilisent des fichiers temporaires et une fusion externe si l'entrée est trop grande pour tenir dans la RAM. Et la plupart des autres versions ont une-m
option, ce qui peut être fait explicitement en découpant l'entrée (par exemple avecsplit
), en triant chaque bloc, puis en fusionnant les morceauxRéponses:
Pour imprimer chaque ligne identique une seule, dans n'importe quel ordre:
Pour imprimer uniquement les lignes uniques, dans n'importe quel ordre:
Pour imprimer chaque ligne identique une seule fois, dans l'ordre de leur première occurrence: (pour chaque ligne, imprimez la ligne si elle n'a pas encore été vue, puis en tout cas incrémentez le compteur vu)
Pour imprimer uniquement les lignes uniques, dans l'ordre de leur première occurrence: (enregistrez chaque ligne dans
seen
et aussilines
s'il s'agit de la première occurrence; à la fin de l'entrée, imprimez les lignes dans l'ordre d'occurrence mais uniquement celles vues uniquement une fois que)la source
awk '!seen[$0]++ {print}'
?awk '!seen[$0]++'
, car le{print}
est impliqué par une commande vide.Certaines (la plupart?) Versions
sort
ont un-u
indicateur qui faituniq
directement la partie. Il peut y avoir des restrictions de longueur de ligne en fonction de l'implémentation, mais vous en aviez déjà avec plainsort|uniq
.la source
sort -u
remonte au moins à V7.-u
mais ont également une restriction de longueur de ligne de 512 caractères. (En fait, je pense que quelque part autour de Solaris 9 Sun l'a augmenté à 5120. GNU gagne toujours, cependant.)Perl fonctionne-t-il pour vous? Il peut conserver les lignes dans l'ordre d'origine, même si les doublons ne sont pas adjacents. Vous pouvez également le coder en Python, ou
awk
.Qui peut être raccourci à seulement
Fichier d'entrée donné:
Il donne la sortie:
la source
use strict;
ouuse warnings;
(en fait, c'est cestrict
qui est le plus pertinent ici), il n'y a pas de problème d'utilisation%lines
avant qu'il ne soit défini. S'il est exécuté avec des restrictions, il devrait y avoir une lignemy %lines;
avant la boucle. Notez également que le hachage est%lines
; un élément du hachage est référencé à l'aide de la$lines{$_}
notation.sort
solutions peuvent être meilleures pour une grande quantité de données (l'OP s'inquiétait de "stocker le fichier entier en mémoire").sort
effectuera un tri hors cœur si les données sont plus grandes que la mémoire disponible.Pour la dernière partie de la réponse mentionnée dans: Impression de lignes uniques par @Gilles comme réponse à cette question, j'ai essayé d'éliminer la nécessité d'utiliser deux hachages.
Cette solution est pour: Pour imprimer uniquement les lignes uniques, dans l'ordre de leur première occurrence:
awk '{counter[$0]++} END {for (line in counter) if (counter[line]==1) print line}'
Ici, "compteur" stocke un nombre de chaque ligne similaire à celui traité précédemment.
À la fin, nous imprimons uniquement les lignes dont la valeur de compteur est 1.
la source