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.
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.