ค้นหาบรรทัดที่ซ้ำกันในไฟล์และนับจำนวนครั้งที่แต่ละบรรทัดถูกทำซ้ำ


529

สมมติว่าฉันมีไฟล์ที่คล้ายกับต่อไปนี้:

123 
123 
234 
234 
123 
345

ฉันต้องการค้นหาว่ามีการทำซ้ำ '123' กี่ครั้งกี่ครั้งที่มีการทำซ้ำ '234' และอื่น ๆ ดังนั้นโดยอุดมคติแล้วผลลัพธ์จะเป็นดังนี้:

123  3 
234  2 
345  1

4
คุณต้องการใช้ภาษาใด
VMAtm

คำตอบ:


791

สมมติว่ามีหนึ่งหมายเลขต่อบรรทัด:

sort <file> | uniq -c

คุณสามารถใช้การ--countตั้งค่าสถานะverbose มากขึ้นด้วยรุ่น GNU เช่นบน Linux:

sort <file> | uniq --count

3
นี่คือสิ่งที่ฉันทำอย่างไรก็ตามอัลกอริทึมนี้ดูเหมือนจะไม่ใช่วิธีที่มีประสิทธิภาพมากที่สุด (O (n log n) * avg_line_len โดยที่ n คือจำนวนบรรทัด) ฉันกำลังทำงานกับไฟล์ที่มีขนาดใหญ่หลายกิกะไบต์ดังนั้นประสิทธิภาพจึงเป็นปัญหาสำคัญ ฉันสงสัยว่ามีเครื่องมือที่ใช้ในการนับในรอบเดียวโดยใช้ต้นไม้คำนำหน้า (ในกรณีของสตริงมักจะมีคำนำหน้าทั่วไป) หรือคล้ายกันที่ควรทำเคล็ดลับใน O (n) * avg_line_len ไม่มีใครรู้เช่นเครื่องมือ commandline?
Droggl

21
ขั้นตอนเพิ่มเติมคือไปป์เอาท์พุทของสิ่งนั้นลงในคำสั่ง 'sort -n' สุดท้าย ที่จะเรียงลำดับผลลัพธ์ตามที่บรรทัดเกิดขึ้นบ่อยที่สุด
samoz

79
หากคุณต้องการพิมพ์บรรทัดที่ซ้ำกันให้ใช้ 'uniq -d'
DmitrySandalov

6
หากคุณต้องการเรียงลำดับผลลัพธ์อีกครั้งคุณอาจใช้sortอีกครั้งเช่น:sort <file> | uniq -c | sort -n
Abhishek Kashyap

413

สิ่งนี้จะพิมพ์บรรทัดที่ซ้ำกันเท่านั้นโดยมีจำนวน:

sort FILE | uniq -cd

หรือด้วยตัวเลือกแบบยาวของ GNU (บน Linux):

sort FILE | uniq --count --repeated

บนBSD และ OSX คุณต้องใช้ grepเพื่อกรองบรรทัดที่ไม่ซ้ำกัน:

sort FILE | uniq -c | grep -v '^ *1 '

สำหรับตัวอย่างที่กำหนดผลลัพธ์จะเป็น:

  3 123
  2 234

หากคุณต้องการพิมพ์การนับสำหรับทุกบรรทัดรวมถึงที่ปรากฏเพียงครั้งเดียว:

sort FILE | uniq -c

หรือด้วยตัวเลือกแบบยาวของ GNU (บน Linux):

sort FILE | uniq --count

สำหรับอินพุตที่กำหนดเอาต์พุตคือ:

  3 123
  2 234
  1 345

เพื่อเรียงลำดับผลลัพธ์ด้วยบรรทัดที่บ่อยที่สุดที่ด้านบนคุณสามารถทำดังต่อไปนี้ (เพื่อให้ได้ผลลัพธ์ทั้งหมด):

sort FILE | uniq -c | sort -nr

หรือเพื่อให้ได้บรรทัดที่ซ้ำกันบ่อยที่สุดก่อน:

sort FILE | uniq -cd | sort -nr

บน OSX และ BSD สุดท้ายจะกลายเป็น:

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr

1
จุดที่ดีกับ --rereated หรือตัวเลือก -d แม่นยำมากกว่าการใช้ "| grep 2" หรือคล้ายกันมาก!
Lauri

ฉันจะแก้ไขคำสั่งนี้เพื่อดึงข้อมูลบรรทัดทั้งหมดที่มีจำนวนการทำซ้ำมากกว่า 100 ได้อย่างไร
Black_Rider

@Black_Rider การเพิ่ม| sort -nหรือ| sort -nrไปที่ไปป์จะเรียงลำดับผลลัพธ์ตามจำนวนการทำซ้ำ (จากน้อยไปมากหรือมากไปหาน้อยตามลำดับ) นี่ไม่ใช่สิ่งที่คุณถาม แต่ฉันคิดว่ามันอาจช่วยได้
Andrea

1
awk @Black_Rider ดูเหมือนว่าสามารถที่จะทำชนิดของการคำนวณทั้งหมด: ในกรณีของคุณคุณจะทำ| awk '$1>100'
อันเดรีย

4
@fionbio ดูเหมือนว่าคุณไม่สามารถใช้ร่วมกัน -c และ -d ใน OSX UNIQ ขอบคุณสำหรับการชี้ให้เห็น คุณสามารถใช้ grep เพื่อกรองบรรทัดที่ไม่ซ้ำกัน :sort FILE | uniq -c | grep -v '^ *1 '
Andrea

72

ในการค้นหาและนับบรรทัดที่ซ้ำกันในหลายไฟล์คุณสามารถลองใช้คำสั่งต่อไปนี้:

sort <files> | uniq -c | sort -nr

หรือ:

cat <files> | sort | uniq -c | sort -nr

30

ผ่านทาง :

awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data

ในawk 'dups[$1]++'คำสั่งตัวแปร$1ถือเนื้อหาทั้งหมดของ column1 และวงเล็บเหลี่ยมคือการเข้าถึงอาร์เรย์ ดังนั้นสำหรับแต่ละคอลัมน์ที่ 1 ของบรรทัดในdataไฟล์โหนดของอาร์เรย์ที่มีชื่อdupsจะเพิ่มขึ้น

และในตอนท้ายเราจะวนลูปกับdupsอาร์เรย์กับnumเป็นตัวแปรและพิมพ์บันทึกหมายเลขdups[num]แรกแล้วจำนวนของพวกเขาที่มีค่าที่ซ้ำกันโดย

โปรดทราบว่าไฟล์อินพุตของคุณมีช่องว่างที่ส่วนท้ายของบางบรรทัดถ้าคุณล้างข้อมูลเหล่านั้นคุณสามารถใช้$0แทน$1คำสั่งด้านบน :)


1
นี่ไม่ใช่ความคิดที่เกินความจริงuniqหรือไม่เพราะเรามี
Nathan Fellman

9
sort | uniqและโซลูชัน awk นั้นมีประสิทธิภาพและการแลกเปลี่ยนทรัพยากรแตกต่างกันมาก: ถ้าไฟล์มีขนาดใหญ่และจำนวนบรรทัดที่ต่างกันมีขนาดเล็กโซลูชัน awk นั้นมีประสิทธิภาพมากกว่ามาก มันเป็นเส้นตรงในจำนวนเส้นและการใช้พื้นที่เป็นเส้นตรงในจำนวนเส้นที่แตกต่างกัน OTOH โซลูชั่น awk ต้องการเก็บทุกบรรทัดในหน่วยความจำไว้ในขณะที่การเรียงลำดับ (GNU) สามารถเปลี่ยนไปใช้ไฟล์ temp ได้
Lars Noschinski

14

ใน windows โดยใช้ "Windows PowerShell"ฉันใช้คำสั่งที่ระบุไว้ด้านล่างเพื่อให้ได้สิ่งนี้

Get-Content .\file.txt | Group-Object | Select Name, Count

นอกจากนี้เรายังสามารถใช้ where-object Cmdlet เพื่อกรองผลลัพธ์

Get-Content .\file.txt | Group-Object | Where-Object { $_.Count -gt 1 } | Select Name, Count

คุณสามารถลบรายการที่ซ้ำทั้งหมดยกเว้นรายการสุดท้าย ... โดยไม่เปลี่ยนลำดับการจัดเรียงของไฟล์ได้หรือไม่
jparram

6

สมมติว่าคุณมีสิทธิ์เข้าถึงเชลล์ Unix มาตรฐานและ / หรือ cygwin:

tr -s ' ' '\n' < yourfile | sort | uniq -d -c
       ^--space char

โดยทั่วไป: แปลงอักขระช่องว่างทั้งหมดเป็น linebreaks จากนั้นเรียงลำดับเอาต์พุต tranlsated และฟีดที่เป็น uniq และนับบรรทัดที่ซ้ำกัน

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