2011-07-15 16 views

Trả lời

544

Giả sử có một số trên mỗi dòng:

sort <file> | uniq -c 

Bạn có thể sử dụng nhiều tiết --count cờ quá với phiên bản GNU, ví dụ, trên Linux:

sort <file> | uniq --count 
+1

Đây là những gì tôi làm tuy nhiên theo thuật toán này không có vẻ là phương pháp hiệu quả nhất (O (n log n) * avg_line_len trong đó n là số dòng). Tôi đang làm việc trên các tệp có dung lượng lớn vài gigabyte, do đó hiệu suất là một vấn đề quan trọng. Tôi tự hỏi liệu có một công cụ chỉ thực hiện việc đếm trong một lần sử dụng một cây tiền tố (trong các chuỗi trường hợp của tôi thường có các tiền tố chung) hay tương tự, nên thực hiện thủ thuật trong O (n) * avg_line_len. Có ai biết một công cụ dòng lệnh như vậy không? – Droggl

+10

Một bước bổ sung là để ống đầu ra của đó thành một lệnh 'sort -n' cuối cùng. Điều đó sẽ sắp xếp các kết quả theo đó các dòng xuất hiện thường xuyên nhất. – samoz

+19

Nếu bạn chỉ muốn in các dòng trùng lặp, hãy sử dụng 'uniq -d' – DmitrySandalov

7

Giả sử bạn đã có quyền truy cập vào một vỏ Unix chuẩn và/hoặc môi trường Cygwin:

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

Về cơ bản: chuyển đổi tất cả các ký tự không gian để linebreaks, sau đó sắp xếp các đầu ra và nguồn cấp dữ liệu tranlsated để uniq và đếm dòng trùng lặp.

58

Để tìm và đếm dòng trùng lặp trong nhiều file, bạn có thể thử lệnh sau:

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

hay:

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

+1 để hiển thị các dòng thường xuyên nhất trên đầu trang –

282

này sẽ dòng in trùng lặp chỉ, với số lượng:

sort FILE | uniq -cd 

hoặc, với tùy chọn dài GNU (trên Linux):

sort FILE | uniq --count --repeated 

trên BSD and OSX you have to use grep để lọc ra các dòng duy nhất:

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

Đối với ví dụ được đưa ra, kết quả sẽ là:

3 123 
    2 234 

Nếu bạn muốn đếm in cho tất cả các dòng bao gồm những dòng chỉ xuất hiện một lần:

sort FILE | uniq -c 

hay, với các tùy chọn GNU dài (trên Linux):

sort FILE | uniq --count 

Đối với đầu vào nhất định, đầu ra là:

3 123 
    2 234 
    1 345 

Để loại đầu ra với các dòng thường xuyên nhất trên đầu trang, bạn có thể làm như sau (để có được tất cả kết quả):

sort FILE | uniq -c | sort -nr 

hay, để có được chỉ lặp lại đường nét, thường xuyên đầu tiên nhất:

sort FILE | uniq -cd | sort -nr 

trên OSX và BSD một trong những thức trở thành:

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

Điểm tốt với tùy chọn --repeated hoặc -d. Chính xác hơn nhiều so với sử dụng "| grep 2" hoặc tương tự! – Lauri

+0

Làm cách nào tôi có thể sửa đổi lệnh này để truy xuất tất cả các dòng có số lần lặp lại lớn hơn 100? –

+0

@Black_Rider Thêm '| sắp xếp -n' hoặc '| sắp xếp -nr' cho đường ống sẽ sắp xếp đầu ra theo số lần lặp lại (tăng dần hoặc giảm dần tương ứng). Đây không phải là những gì bạn đang yêu cầu nhưng tôi nghĩ rằng nó có thể giúp đỡ. – Andrea

19

Via :

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

Trong lệnh awk 'dups[$1]++', biến số $1 giữ toàn bộ nội dung của cột1 và dấu ngoặc vuông là truy cập mảng. Vì vậy, đối với mỗi cột 1 của dòng trong tệp data, nút của mảng có tên là dups được tăng lên.

Và cuối cùng, chúng ta lặp qua dups mảng với num như biến và in lưu số đầu tiên sau đó số lượng của họ về giá trị trùng lặp bởi dups[num].

Lưu ý rằng tập tin đầu vào của bạn có không gian kết thúc của một số dòng, nếu bạn rõ ràng lên đó, bạn có thể sử dụng $0 ở vị trí của $1 trong lệnh trên :)

+1

Đây có phải là một chút quá mức cần thiết khi chúng ta có 'uniq'? –

+6

'sắp xếp | uniq' và giải pháp awk có hiệu suất khá khác nhau và tài nguyên thương mại-off: nếu các tập tin lớn và số lượng các dòng khác nhau là nhỏ, giải pháp awk là rất nhiều hiệu quả hơn. Nó là tuyến tính trong số dòng và cách sử dụng không gian là tuyến tính theo số lượng các dòng khác nhau. OTOH, giải pháp awk cần phải giữ tất cả các dòng khác nhau trong bộ nhớ, trong khi (GNU) sắp xếp có thể nghỉ mát đến các tập tin tạm thời. –

7

Trong cửa sổ sử dụng "Windows PowerShell" tôi sử dụng lệnh đề cập dưới đây để đạt được điều này

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

Ngoài ra chúng tôi có thể sử dụng cmdlet nơi đối tượng để lọc kết quả

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

bạn có thể xóa tất cả các lần xuất hiện của các bản sao trừ bản sao cuối cùng ... mà không thay đổi thứ tự sắp xếp của tệp không? – jparram