Sắp xếp và đếm số lần xuất hiện của các dòng


145

Tôi có Apachelogfile, access.loglàm thế nào để đếm số lần xuất hiện dòng trong tệp đó? ví dụ kết quả 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

kết quả mà tôi muốn là:

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

ah Tôi không bao giờ biết rằng uniqcó thể làm điều đó ..
Kokizzu

Bạn có một ví dụ về dòng trong nhật ký, vì tôi nghĩ rằng tất cả có thể được thực hiện với awk mà không cần tất cả các đường ống.

Không sao, tệp nhật ký 8.1GB được xử lý trong khoảng 2 phút và hiện đã được thực hiện, không còn cần điều này nữa: 3
Kokizzu

Câu trả lời:


196
| sort | uniq -c

Như đã nêu trong các ý kiến.

Đường ống đầu ra thành sorttổ chức đầu ra theo thứ tự chữ cái / số.

Đây là một yêu cầu vì uniqchỉ khớp trên các dòng lặp lại, tức là

a
b
a

Nếu bạn sử dụng uniqtrên tệp văn bản này, nó sẽ trả về như sau:

a
b
a

Điều này là do hai as được phân tách bằng dấu b- chúng không phải là các đường liên tiếp. Tuy nhiên nếu trước tiên bạn sắp xếp dữ liệu theo thứ tự bảng chữ cái như trước

a
a
b

Sau đó uniqsẽ loại bỏ các dòng lặp lại. Các -ctùy chọn của uniqđếm số lượng bản sao và cung cấp đầu ra theo hình thức:

2 a
1 b

Người giới thiệu:


1
Chào mừng bạn đến với Unix & Linux :) Đừng ngần ngại thêm chi tiết vào câu trả lời của bạn và giải thích lý do và cách thức hoạt động của nó;)
John WH Smith

1
printf '%s\n' ①.php ②.php | sort | uniq -ccho tôi2 ①.php
Stéphane Chazelas

@ StéphaneChazelas Thats vì bản in printfphp\nphp

4
@Jidder, không, đó là vì ①.phpsắp xếp giống như ②.phpở địa phương của tôi vì không có thứ tự sắp xếp nào được xác định cho những người nhân vật trong địa phương của tôi. Nếu bạn muốn các giá trị duy nhất cho bất kỳ giá trị byte nào (hãy nhớ đường dẫn tệp không nhất thiết phải là văn bản), thì bạn cần sửa ngôn ngữ thành C : | LC_ALL=C sort | LC_ALL=C uniq -c.
Stéphane Chazelas

2
Để sắp xếp tệp đếm kết quả, bạn nên xem xét thêm "sort -nr" dưới dạng câu trả lời @ eduard-florinescu bên dưới.
Lluís Suñol

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

Câu trả lời được chấp nhận gần như hoàn tất, bạn có thể muốn thêm phần bổ sung sort -nrvào cuối để sắp xếp kết quả với các dòng xảy ra thường xuyên nhất trước tiên

tùy chọn uniq :

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

tùy chọn sắp xếp :

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

Trong trường hợp cụ thể là các dòng bạn sắp xếp là số, bạn cần sử dụng sort -grthay vì sort -nr, xem bình luận


3
Cảm ơn rất nhiều vì đã cho tôi biết về -nlựa chọn.
Sigur

2
Câu trả lời tuyệt vời, đây là những gì tôi sử dụng để lấy một từ trong tập tin với câu : tr ' ' '\n' < $FILE | sort | uniq -c | sort -nr > wordcount.txt. Lệnh đầu tiên thay thế khoảng trắng bằng dòng mới, cho phép phần còn lại của lệnh hoạt động như mong đợi.
Bar

2
Sử dụng các tùy chọn ở trên, tôi nhận được "1" trước "23344". Sử dụng sort -grthay vì giải quyết điều này. -g: so sánh theo giá trị số chung (thay vì -n: so sánh theo giá trị số chuỗi).
Peter Jaric

@PeterJaric Bắt tuyệt vời và rất hữu ích để biết -grnhưng tôi nghĩ đầu ra của uniq -csort -nrsẽ hoạt động như dự định
Eduard Florinescu

3
Trên thực tế, khi dữ liệu là số, -grhoạt động tốt hơn. Hãy thử hai ví dụ này, chỉ khác nhau ở cờ g và n: echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -nrecho "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -gr. Cái thứ nhất sắp xếp không chính xác, nhưng không phải cái thứ hai.
Peter Jaric

9

Bạn có thể sử dụng một mảng kết hợp trên awk và sau đó -optionally- sort :

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

đầu ra:

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

Làm thế nào bạn sẽ đếm số lần xuất hiện khi đường ống đang gửi dữ liệu?
user123456
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.