J'ai trouvé la sed
réponse peu de temps après avoir posté cette question; personne d'autre n'a utilisé sed
jusqu'à présent, alors voici:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
Un peu de jeu avec le problème plus général (qu'en est-il de la suppression de lignes par ensembles de trois? Ou quatre ou cinq?) A fourni la solution extensible suivante:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
Étendu pour supprimer des triplets de lignes:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
Ou pour supprimer des quads de lignes:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
a un avantage supplémentaire par rapport à la plupart des autres options, qui est sa capacité à vraiment fonctionner dans un flux, sans plus de stockage en mémoire nécessaire que le nombre réel de lignes à vérifier pour les doublons.
Comme cuonglm l'a souligné dans les commentaires , la définition des paramètres régionaux sur C est nécessaire pour éviter les échecs de suppression correcte des lignes contenant des caractères multi-octets. Ainsi, les commandes ci-dessus deviennent:
LC_ALL=C sed '$!N;/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
# Etc.
Caractère générique
la source
C
, sinon dans les paramètres régionaux à plusieurs octets, un caractère non valide dans ces paramètres régionaux entraînera l'échec de la commande.Ce n'est pas très élégant, mais c'est aussi simple que possible:
Le substr () coupe juste la
uniq
sortie. Cela fonctionnera jusqu'à ce que vous ayez plus de 9 999 999 doublons d'une ligne (dans ce cas, la sortie d'uniq peut déborder de 9 caractères).la source
uniq -c input | awk '{if ($1 %2 == 1) { print $2 } }'
et cela a semblé fonctionner aussi bien. Une raison pour laquelle lasubstr
version est meilleure?$2
pour$NF
être plus robuste?foo bar
.uniq
(au moins dans GNU coreutils) semble utiliser de manière fiable exactement 9 caractères avant le texte lui-même; Cependant, je ne trouve cela documenté nulle part, et ce n'est pas dans les spécifications POSIX .Essayez ce
awk
script ci-dessous:Il est supposé que le
lines.txt
fichier est trié.Le test:
la source
Avec
pcregrep
pour un échantillon donné:ou d'une manière plus générale:
la source
Si l'entrée est triée:
la source
pineapple\napple\ncoconut
et la sortie estpinecoconut
.\n
au lieu de$
donner le/m
modificateur, mais j'ai réalisé que l'utilisation$
laisserait une ligne vierge à la place des lignes supprimées. A l'air bien maintenant; J'ai supprimé la version incorrecte car elle n'a fait qu'ajouter du bruit. :)J'aime
python
ça, par exemple avecpython
2.7+la source
Comme j'ai compris la question, j'ai opté pour awk, en utilisant un hachage de chaque enregistrement, dans ce cas, je suppose que RS = \ n, mais il peut être modifié pour prendre en compte tout autre type d'arrangements, il peut être organisé pour considérer un nombre pair de répétitions, au lieu de l'impaire, avec un paramètre ou une petite boîte de dialogue. Chaque ligne est utilisée comme hachage et son nombre augmente, à la fin du fichier, le tableau est analysé et imprime chaque nombre pair de l'enregistrement. J'inclus le nombre afin de vérifier mais, la suppression d'un [x] est suffisante pour résoudre ce problème.
HTH
code de compte à rebours
Exemples de données:
Exemple d'exécution:
la source
awk
code, mais malheureusement,awk
les tableaux associatifs ne sont pas du tout ordonnés, ni ne préservent l'ordre.sort
.!=0
est impliqué par la façon dontawk
convertit les nombres en valeurs vraies / fausses, ce qui rend cela réductible àawk '{a[$0]++}END{for(x in a)if(a[x]%2)print x}'
Si l'entrée est triée, qu'en est-il
awk
:la source
avec perl:
la source
En utilisant des constructions shell,
la source
$b
).Puzzle amusant!
En Perl:
Verbosely dans Haskell:
Tersely à Haskell:
la source
une version: j'utilise des "délimiteurs" pour simplifier la boucle intérieure (il suppose que la première ligne ne l'est pas
__unlikely_beginning__
et il suppose que le texte ne se termine pas par la ligne__unlikely_ending__
:, et j'ajoute cette ligne de délimitation spéciale à la fin des lignes entrées. l'algorithme peut supposer les deux:)Donc :
la source