วิธีการลบบรรทัดที่ซ้ำกันด้วย awk ในขณะที่รักษาบรรทัดว่างอยู่?


13

awkคำสั่งด้านล่างจะลบบรรทัดที่ซ้ำกันทั้งหมดตามที่อธิบายไว้ที่นี่ :

awk '!seen[$0]++'

หากข้อความมีบรรทัดว่างทั้งหมด แต่บรรทัดว่างหนึ่งบรรทัดจะถูกลบ

ฉันจะเก็บบรรทัดว่างไว้ทั้งหมดในขณะที่ลบบรรทัดที่ซ้ำกันที่ไม่ว่างทั้งหมดโดยใช้เพียงอย่างเดียวได้awkอย่างไร โปรดรวมคำอธิบายสั้น ๆ

คำตอบ:



11

อีกทางเลือกหนึ่ง

awk '!/./ || !seen[$0]++' file

เคล็ดลับหลักเหมือนกันseen[$0]++สร้างรายการในseenอาร์เรย์ที่เชื่อมโยงกันซึ่งมีคีย์คือบรรทัดปัจจุบัน ( $0) ดังนั้น!seen[$0]++จะเป็นเท็จหากเห็นบรรทัดนี้แล้ว /./คือการตรวจสอบว่าสายประกอบด้วยอักขระที่ไม่ใช่ช่องว่างใด ๆ เพื่อให้!/./ตรงกับบรรทัดว่างไม่ใช่ รวมกับ || !seen[$0]++มันจะไม่สนใจบรรทัดที่ซ้ำกันทั้งหมดยกเว้นที่ว่างเปล่าและพิมพ์ส่วนที่เหลือ


ฉันคิดว่านี่น่าจะเป็นคำตอบที่ยอมรับได้ +1 สำหรับคำอธิบาย!
SS Anne

5
awk '/^[[:blank:]]*$/ { print; next; }; !seen[$0]++'

สิ่งที่คุณต้องทำคือตรวจสอบบรรทัดว่างเปล่า (ว่างเปล่าจริงๆหรือว่างเปล่า) ก่อน


5

นี่เป็นอีกawkวิธีการหนึ่งซึ่งคล้ายกับคำตอบของ @ Thor มีความกระชับน้อยลง แต่มีประสิทธิภาพมากขึ้น:

awk '!NF {print;next}; !($0 in a) {a[$0];print}' file

ด้วยสิ่งนี้เราตรวจสอบเท่านั้นที่a[$0]มีอยู่หรือไม่ ถ้าไม่เริ่มต้นก็พิมพ์ ในกรณีนี้เราไม่มีการอ้างอิงใด ๆ กำหนดa[$0]ถ้ามันมีอยู่


ฉันไม่ได้วัดความแตกต่างของเวลาที่สำคัญกับไฟล์ทดสอบ 288 บรรทัดของฉัน อย่างไรก็ตามรหัสของคุณจะดึงดูดผู้อ่านที่ได้รับรางวัลมากที่สุด
Serge Stroobandt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.