Ho elaborato la sed
risposta non molto tempo dopo aver pubblicato questa domanda; nessun altro ha usato sed
finora così eccolo qui:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
Un po 'a giocare con il problema più generale (che dire di eliminare le righe in gruppi di tre? O quattro, o cinque?) Ha fornito la seguente soluzione estensibile:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
Esteso per rimuovere le triple di linee:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
O per rimuovere i quadratini di linee:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
ha un ulteriore vantaggio rispetto alla maggior parte delle altre opzioni, che è la sua capacità di operare veramente in un flusso, senza bisogno di più memoria di memoria rispetto al numero effettivo di linee da controllare per i duplicati.
Come ha sottolineato cuonglm nei commenti , è necessario impostare le impostazioni locali su C per evitare errori nel rimuovere correttamente le righe contenenti caratteri multibyte. Quindi i comandi sopra diventano:
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
, altrimenti nelle impostazioni internazionali multibyte, il carattere non valido in tale impostazione locale non riuscirà .