Saya menemukan sed
jawabannya tidak lama setelah saya memposting pertanyaan ini; tidak ada orang lain yang telah menggunakan sed
sejauh ini jadi ini dia:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
Sedikit bermain-main dengan masalah yang lebih umum (bagaimana dengan menghapus garis di set tiga? Atau empat, atau lima?) Memberikan solusi yang dapat diperluas berikut:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
Diperpanjang untuk menghapus tiga kali lipat garis:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
Atau untuk menghapus quads of lines:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
memiliki keunggulan tambahan dibandingkan sebagian besar opsi lain, yaitu kemampuannya untuk benar-benar beroperasi dalam aliran, tanpa penyimpanan memori yang lebih dibutuhkan daripada jumlah baris aktual yang akan diperiksa untuk duplikat.
Seperti ditunjukkan cuonglm dalam komentar , pengaturan lokal ke C diperlukan untuk menghindari kegagalan untuk menghapus baris yang berisi karakter multi-byte dengan benar. Jadi perintah di atas menjadi:
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
, jika tidak dalam multi-byte lokal, karakter yang tidak valid di lokal itu menyebabkan perintah gagal.