Đếm tất cả các lần xuất hiện của một chuỗi trong nhiều tệp với grep


289

Tôi có một loạt các tập tin nhật ký. Tôi cần tìm hiểu bao nhiêu lần một chuỗi xảy ra trong tất cả các tệp.

grep -c string *

trả lại

...
file1:1
file2:0
file3:0
...

Sử dụng một đường ống tôi chỉ có thể nhận được các tệp có một hoặc nhiều lần xuất hiện:

grep -c string * | grep -v :0

...
file4:5
file5:1
file6:2
...

Làm thế nào tôi chỉ có thể nhận được số lượng kết hợp? (Nếu nó trở lại file4:5, file5:1, file6:2, tôi muốn lấy lại 8.)


1
Bạn có thể cho tôi biết grep -v: 0 làm gì không? . Tôi biết nó được tính cho các tệp có số lần xuất hiện lớn hơn 0. Tùy chọn -v và: 0 có nghĩa là gì ?. Vui lòng cho tôi biết.
Gautham Honnavara

@GauthamHonnavara grep: 0 tìm dòng khớp với chuỗi: 0. -v là một tùy chọn để đảo ngược tìm kiếm đó, thay vào đó, sử dụng grep -v: 0 có nghĩa là tìm tất cả các dòng không chứa: 0 vì vậy một dòng có tệp4: 5 và tệp27: 193 tất cả sẽ đi qua vì chúng không chứa: 0
chim cánh cụt359

Bạn có thể chọn nhiều tệp bằng cách sử dụng không gian. grep file1 file2 --options
Dnyaneshwar Harer

Câu trả lời:


288
cat * | grep -c string

9
Điều này có cùng một giới hạn là nó chỉ tính nhiều lần xuất hiện trên một dòng. Tôi đoán rằng hành vi này là OK trong trường hợp này, mặc dù.
Michael Haren

@Michael Haren Có, chỉ có một lần xuất hiện chuỗi trong một dòng.
Željko Filipin

2
Tôi thà làm grep -c string<*vậy nên chỉ cần thay thế không gian bằng một ít hơn.
JamesM-SiteGen

48
Không giải quyết nhiều lần xuất hiện trên một dòng
bluesman

2
Điều này không hoạt động nếu bạn muốn tìm kiếm trong thư mục con quá, trong khi grep -owc -lkhông. mèo là nhanh hơn trong các trường hợp như câu hỏi ban đầu mặc dù.
Leassaidh Gordon

296

Điều này hoạt động cho nhiều lần xuất hiện trên mỗi dòng:

grep -o string * | wc -l

2
Điều này cũng hoạt động : grep -o string * --exclude-dir=some/dir/one/ --exclude-dir=some/dir/two | wc -l.
một lập trình viên

2
grep -ioR string * | wc -llà những gì tôi sử dụng để thực hiện tìm kiếm không phân biệt chữ hoa chữ thường, đệ quy, chỉ khớp
LeonardChallis

2
Cái này hiển thị các tập tin liên quan và sau đó tổng số trận đấu:grep -rc test . | awk -F: '$NF > 0 {x+=$NF; $NF=""; print} END{print "Total:",x}'
Yaron

28
grep -oh string * | wc -w

sẽ tính nhiều lần xuất hiện trong một dòng


24
grep -oh "... my that curry was strong" * >> wc:)
icc97

23

Thay vì sử dụng -c, chỉ cần đặt nó vào wc -l.

grep string * | wc -l

Điều này sẽ liệt kê mỗi lần xuất hiện trên một dòng và sau đó đếm số lượng dòng.

Điều này sẽ bỏ lỡ các trường hợp trong đó chuỗi xảy ra hơn 2 lần trên một dòng.


2
Đường ống đến "wc -l" cũng hoạt động độc đáo cùng với "grep -r 'test'." quét đệ quy tất cả các tệp cho chuỗi 'test' trong tất cả các thư mục bên dưới tệp hiện tại.
stevek

16
cat * | grep -c string

Một trong những ứng dụng hữu ích hiếm có của cat.


9

Một cái gì đó khác với tất cả các câu trả lời trước:

perl -lne '$count++ for m/<pattern>/g;END{print $count}' *

Rất vui khi thấy một cách tiếp cận không sử dụng grep, đặc biệt là grep của tôi (trên windows) không hỗ trợ tùy chọn -o.
David Roussel

9

Bạn có thể thêm -Rvào tìm kiếm đệ quy (và tránh sử dụng mèo) và -Ibỏ qua các tệp nhị phân.

grep -RIc string .

7

Giải pháp AWK bắt buộc:

grep -c string * | awk 'BEGIN{FS=":"}{x+=$2}END{print x}'

Hãy cẩn thận nếu tên tệp của bạn bao gồm ":" mặc dù.


5

Giải pháp AWK cũng xử lý tên tệp bao gồm dấu hai chấm:

grep -c string * | sed -r 's/^.*://' | awk 'BEGIN{}{x+=$1}END{print x}'

Hãy nhớ rằng phương pháp này vẫn không tìm thấy nhiều lần xuất hiện stringtrên cùng một dòng.


4

Nếu bạn muốn số lần xuất hiện trên mỗi tệp (ví dụ cho chuỗi "tcp"):

grep -RIci "tcp" . | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr

Ví dụ đầu ra:

53  ./HTTPClient/src/HTTPClient.cpp
21  ./WiFi/src/WiFiSTA.cpp
19  ./WiFi/src/ETH.cpp
13  ./WiFi/src/WiFiAP.cpp
4   ./WiFi/src/WiFiClient.cpp
4   ./HTTPClient/src/HTTPClient.h
3   ./WiFi/src/WiFiGeneric.cpp
2   ./WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino
2   ./WiFiClientSecure/src/ssl_client.cpp
1   ./WiFi/src/WiFiServer.cpp

Giải trình:

  • grep -RIci NEEDLE . - tìm chuỗi NEEDLE đệ quy từ thư mục hiện tại (theo các liên kết tượng trưng), bỏ qua các nhị phân, đếm số lần xuất hiện, bỏ qua trường hợp
  • awk ... - lệnh này bỏ qua các tệp có số lần xuất hiện và định dạng dòng
  • sort -hr - sắp xếp các dòng theo thứ tự ngược theo số trong cột đầu tiên

Tất nhiên, nó cũng hoạt động với các lệnh grep khác với tùy chọn -c(tính). Ví dụ:

grep -c "tcp" *.txt | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr

3

Bạn có thể sử dụng một cách đơn giản grepđể nắm bắt số lần xuất hiện một cách hiệu quả. Tôi sẽ sử dụng -itùy chọn để đảm bảo STRING/StrING/stringđược chụp đúng cách.

Dòng lệnh cung cấp tên của tệp:

grep -oci string * | grep -v :0

Dòng lệnh xóa tên tệp và in 0 nếu có tệp không xuất hiện:

grep -ochi string *

Bạn có thể vui lòng giải thích thêm câu trả lời của bạn thêm một chút mô tả về giải pháp bạn cung cấp không?
abarisone

3

biến thể đệ quy ngắn :

find . -type f -exec cat {} + | grep -c 'string'

1
Cảm ơn bạn! Chỉ có giải pháp của bạn làm việc cho tôi (tóm tắt các trận đấu của tất cả các tệp).
Nestor

1

Giải pháp duy nhất mà tôi đã thử nghiệm với grep cho windows:

grep -ro "pattern to find in files" "Directory to recursively search" | grep -c "pattern to find in files"

Giải pháp này sẽ tính tất cả các lần xuất hiện ngay cả khi có nhiều trên một dòng. -rtìm kiếm đệ quy thư mục, -osẽ "chỉ hiển thị một phần của dòng khớp với MẪU" - đây là phần phân tách nhiều lần xuất hiện trên một dòng và làm cho grep in mỗi trận đấu trên một dòng mới; sau đó chuyển các kết quả được phân tách bằng dòng mới thành grep -cđể đếm số lần xuất hiện bằng cách sử dụng cùng một mẫu.


1

Dưới đây là cách thay thế AWK nhanh hơn grep để thực hiện việc này, xử lý nhiều kết quả khớp <url>trên mỗi dòng, trong một tập hợp các tệp XML trong một thư mục:

awk '/<url>/{m=gsub("<url>","");total+=m}END{print total}' some_directory/*.xml

Điều này hoạt động tốt trong trường hợp một số tệp XML không có ngắt dòng.


0

Một oneliner khác sử dụng các hàm dòng lệnh cơ bản xử lý nhiều lần xuất hiện trên mỗi dòng.

 cat * |sed s/string/\\\nstring\ /g |grep string |wc -l
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.