Resolví la sed
respuesta poco después de publicar esta pregunta; nadie más ha usadosed
hasta ahora, así que aquí está:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
Un poco de juego con el problema más general (¿qué hay de eliminar líneas en conjuntos de tres? ¿O cuatro o cinco?) Proporcionó la siguiente solución extensible:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
Extendido para eliminar triples de líneas:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
O para eliminar cuadrantes de líneas:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
tiene una ventaja adicional sobre la mayoría de las otras opciones, que es su capacidad de operar realmente en una secuencia, sin necesidad de más almacenamiento de memoria que el número real de líneas para verificar si hay duplicados.
Como Cuonglm señaló en los comentarios , es necesario establecer la configuración regional en C para evitar fallas al eliminar correctamente las líneas que contienen caracteres de varios bytes. Entonces los comandos anteriores se convierten en:
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
, de lo contrario, en la configuración regional de varios bytes, los caracteres no válidos en esa configuración regional causarán un error en el comando.