เรียงลำดับและนับจำนวนการเกิดบรรทัด


145

ฉันมีApachelogfile access.logจะนับจำนวนบรรทัดที่เกิดขึ้นในไฟล์นั้นได้อย่างไร ตัวอย่างเช่นผลลัพธ์ของcut -f 7 -d ' ' | cut -d '?' -f 1 | tr '[:upper:]' '[:lower:]'คือ

a.php
b.php
a.php
c.php
d.php
b.php
a.php

ผลลัพธ์ที่ฉันต้องการคือ:

3 a.php
2 b.php
1 d.php # order doesn't matter
1 c.php 

25
| sort | uniq -c
Costas

3
| LC_ALL=C sort | LC_ALL=C uniq -c
Stéphane Chazelas

อาฉันไม่เคยรู้ว่าuniqจะทำอย่างนั้น ..
Kokizzu

คุณมีตัวอย่างของบรรทัดในบันทึกเพราะฉันคิดว่าทั้งหมดนี้สามารถทำได้ด้วย awk โดยไม่ต้องไปป์ทั้งหมด

มันใช้ได้ไฟล์บันทึก 8.1GB ที่ประมวลผลในเวลาประมาณ 2 นาทีและเสร็จเรียบร้อยแล้วตอนนี้ไม่ต้องการสิ่งนี้อีกต่อไป: 3
Kokizzu

คำตอบ:


196
| sort | uniq -c

ตามที่ระบุไว้ในความคิดเห็น

การส่งออกไปป์ไลน์เพื่อsortจัดระเบียบเอาต์พุตตามลำดับตัวอักษร / ตัวเลข

สิ่งนี้เป็นข้อกำหนดเนื่องจากuniqจะจับคู่เฉพาะบนบรรทัดที่ซ้ำกันเท่านั้น

a
b
a

ถ้าคุณใช้uniqกับไฟล์ข้อความมันจะคืนค่าดังต่อไปนี้:

a
b
a

นี่เป็นเพราะทั้งสองaแยกจากกันโดยb- พวกเขาไม่ใช่เส้นติดต่อกัน อย่างไรก็ตามหากคุณเรียงลำดับข้อมูลตามลำดับตัวอักษรก่อน

a
a
b

จากนั้นuniqจะลบบรรทัดการทำซ้ำ -cตัวเลือกในการuniqนับจำนวนที่ซ้ำกันและให้การส่งออกในรูปแบบ:

2 a
1 b

อ้างอิง:


1
ยินดีต้อนรับสู่ Unix & Linux :) อย่าลังเลที่จะเพิ่มรายละเอียดเพิ่มเติมในคำตอบของคุณและอธิบายว่าทำไมและวิธีการทำงานนี้)
John WH Smith

1
printf '%s\n' ①.php ②.php | sort | uniq -cให้ฉัน2 ①.php
Stéphane Chazelas

@ StéphaneChazelasนั่นเป็นเพราะ printf พิมพ์php\nphp

4
@Jidder ไม่นั่นเป็นเพราะ①.phpเรียงลำดับเช่นเดียวกับ②.phpในภาษาของฉันเพราะไม่มีการกำหนดลำดับการเรียงสำหรับสิ่งเหล่านั้นและตัวละครในภาษาของฉัน หากคุณต้องการที่ไม่ซ้ำกันค่าสำหรับค่าไบต์ใด ๆ (จำเส้นทางแฟ้มไม่จำเป็นต้องมีข้อความ) แล้วคุณจะต้องแก้ไขสถานที่เกิดเหตุที่ | LC_ALL=C sort | LC_ALL=C uniq -cC:
Stéphane Chazelas

2
เพื่อให้มีการจัดเรียงไฟล์นับผลลัพธ์คุณควรพิจารณาเพิ่ม "sort -nr" เป็น @ eduard-florinescu คำตอบด้านล่าง
LluísSuñol

104
[your command] | sort | uniq -c | sort -nr

คำตอบที่ยอมรับนั้นเกือบจะสมบูรณ์แล้วคุณอาจต้องการเพิ่มsort -nrส่วนท้ายเพื่อเรียงลำดับผลลัพธ์ด้วยบรรทัดที่เกิดขึ้นบ่อยที่สุดก่อน

ตัวเลือกuniq :

-c, --count
       prefix lines by the number of occurrences

ตัวเลือกการจัดเรียง :

-n, --numeric-sort
       compare according to string numerical value
-r, --reverse
       reverse the result of comparisons

ในกรณีเฉพาะคือบรรทัดที่คุณเรียงลำดับคือตัวเลขคุณต้องใช้sort -grแทนsort -nrดูความคิดเห็น


3
ขอบคุณมากที่แจ้งให้ฉันทราบเกี่ยวกับ-nตัวเลือก
Sigur

2
คำตอบที่ดีนี่คือสิ่งที่ผมใช้จะได้รับ wordcount tr ' ' '\n' < $FILE | sort | uniq -c | sort -nr > wordcount.txtออกจากไฟล์ที่มีประโยค: คำสั่งแรกแทนที่ช่องว่างด้วยการขึ้นบรรทัดใหม่ทำให้ส่วนที่เหลือของคำสั่งทำงานตามที่คาดไว้
บาร์

2
ใช้ตัวเลือกข้างต้นฉันได้รับ "1" ก่อน "23344" ใช้sort -grแทนแก้ปัญหานี้ -g: เปรียบเทียบตามค่าตัวเลขทั่วไป (แทน-n: เปรียบเทียบตามค่าตัวเลขสตริง)
Peter Jaric

@PeterJaric จับที่ดีและมีประโยชน์มากที่จะรู้เกี่ยวกับ-grแต่ฉันคิดว่าการส่งออกของuniq -cจะเป็นเช่นนั้น sort -nrจะทำงานได้ตามที่ตั้งใจไว้
เอดูอาร์ Florinescu

3
ที่จริงแล้วเมื่อข้อมูลเป็นตัวเลขก็จะ-grทำงานได้ดีขึ้น ลองทั้งสองตัวอย่างที่แตกต่างกันเฉพาะในกรัมและ n ธง: และecho "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -nr echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -grคนแรกเรียงลำดับไม่ถูกต้อง แต่ไม่ใช่คนที่สอง
Peter Jaric

9

คุณสามารถใช้อาเรย์แบบเชื่อมโยงบนawkและ -optionally- sort :

cat access.log  | awk ' { tot[$0]++ } END { for (i in tot) print tot[i],i } ' | sort

เอาท์พุท:

1 c.php
1 d.php
2 b.php
3 a.php

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