ฉันหาsed
คำตอบได้ไม่นานหลังจากฉันโพสต์คำถามนี้ ไม่มีใครใช้มาsed
จนถึงตอนนี้ที่นี่:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
การเล่นเล็ก ๆ น้อย ๆ ที่มีปัญหาทั่วไปมากขึ้น (สิ่งที่เกี่ยวกับการลบบรรทัดในชุดที่สามหรือสี่หรือห้า?) ให้วิธีแก้ปัญหาที่ขยายได้ดังต่อไปนี้:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
ขยายเพื่อลบสามบรรทัด:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
หรือเพื่อลบบรรทัดที่สี่:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
มีข้อได้เปรียบเพิ่มเติมจากตัวเลือกอื่น ๆ ส่วนใหญ่ซึ่งเป็นความสามารถในการใช้งานในสตรีมอย่างแท้จริงโดยไม่ต้องมีที่เก็บข้อมูลหน่วยความจำเกินจำนวนสายที่แท้จริงที่จะตรวจสอบซ้ำ
ตามที่cuonglm ชี้ให้เห็นในความคิดเห็นการตั้งค่าโลแคลเป็น C จำเป็นเพื่อหลีกเลี่ยงความล้มเหลวในการลบบรรทัดที่มีอักขระหลายไบต์อย่างถูกต้อง ดังนั้นคำสั่งข้างต้นกลายเป็น:
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
มิฉะนั้นในหลายโลแคลอักขระไม่ถูกต้องในโลแคลนั้นทำให้คำสั่งล้มเหลว