นับจำนวนสตริงทั้งหมดในไฟล์จำนวนมากที่มี grep


289

ฉันมีไฟล์บันทึกมากมาย ฉันต้องการค้นหาว่าสตริงมีกี่ครั้งในไฟล์ทั้งหมด

grep -c string *

ผลตอบแทน

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

การใช้ไพพ์ฉันสามารถได้รับไฟล์ที่มีเหตุการณ์อย่างน้อยหนึ่งอย่างเท่านั้น:

grep -c string * | grep -v :0

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

ฉันจะได้รับการนับรวมเท่านั้นได้อย่างไร (ถ้ามันกลับfile4:5, file5:1, file6:2มาฉันต้องการกลับ 8)


1
คุณสามารถบอกฉันได้ว่า grep -v: 0 ทำอะไรได้บ้าง . ฉันรู้ว่ามันนับว่ามีไฟล์เกิดขึ้นมากกว่า 0 ตัวเลือก -v และ: 0 หมายถึงอะไร? กรุณาแจ้งให้เราทราบ
Gautham Honnavara

@GauthamHonnavara grep: 0 ค้นหาบรรทัดที่ตรงกับสตริง: 0 -v เป็นตัวเลือกในการกลับด้านการค้นหาดังนั้นแทนที่จะใช้ grep -v: 0 หมายถึงค้นหาบรรทัดทั้งหมดที่ไม่มี: 0 ดังนั้นบรรทัดที่มี file4: 5 และ file27: 193 ทั้งหมดจะผ่านเนื่องจากไม่มี: 0
penguin359

คุณสามารถเลือกหลายไฟล์โดยใช้พื้นที่ grep file1 file2 --options
Dnyaneshwar

คำตอบ:


288
cat * | grep -c string

9
สิ่งนี้มีข้อ จำกัด เหมือนกันที่จะนับการเกิดขึ้นหลายครั้งในหนึ่งบรรทัดเพียงครั้งเดียว ฉันเดาว่าพฤติกรรมนี้ใช้ได้ในกรณีนี้
Michael Haren

@Michael Haren ใช่อาจมีสตริงเกิดขึ้นเพียงครั้งเดียวเท่านั้น
Željko Filipin

2
ฉันควรทำgrep -c string<*อย่างนั้นเพียงแค่แทนที่พื้นที่ด้วยน้อยกว่า
JamesM-SiteGen

48
อย่ากล่าวถึงเหตุการณ์ที่เกิดขึ้นหลายครั้งบนเส้น
bluesman

2
วิธีนี้ใช้ไม่ได้หากคุณต้องการค้นหาในไดเรกทอรีย่อยด้วยในขณะที่grep -oและwc -lใช้ แมวนั้นเร็วกว่าในกรณีเช่นคำถามเดิม
Leagsaidh Gordon

296

สิ่งนี้ใช้ได้กับการเกิดขึ้นหลายครั้งต่อบรรทัด:

grep -o string * | wc -l

2
grep -o string * --exclude-dir=some/dir/one/ --exclude-dir=some/dir/two | wc -lนอกจากนี้ยังทำงาน:
coder

2
grep -ioR string * | wc -lคือสิ่งที่ฉันใช้เพื่อทำการค้นหาแบบตรงตามตัวพิมพ์เล็กใหญ่เรียกซ้ำและจับคู่เท่านั้น
LeonardChallis

2
ไฟล์นี้แสดงไฟล์ที่เกี่ยวข้องแล้วนับการแข่งขันทั้งหมด:grep -rc test . | awk -F: '$NF > 0 {x+=$NF; $NF=""; print} END{print "Total:",x}'
Yaron

28
grep -oh string * | wc -w

จะนับเหตุการณ์หลายรายการในหนึ่งบรรทัด


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

23

แทนที่จะใช้ -c เพียงแค่ไพพ์ไปที่ wc -l

grep string * | wc -l

สิ่งนี้จะแสดงรายการที่เกิดขึ้นในแต่ละบรรทัดแล้วนับจำนวนบรรทัด

สิ่งนี้จะทำให้อินสแตนซ์ของสตริงเกิดขึ้น 2+ ครั้งในหนึ่งบรรทัด


2
การวางท่อกับ "wc -l" ก็ทำงานได้เป็นอย่างดีพร้อมกับ "grep -r 'test'" ซึ่งจะสแกนไฟล์ทั้งหมดซ้ำเพื่อหาสตริง 'ทดสอบ' ในไดเรกทอรีทั้งหมดที่อยู่ใต้ไฟล์ปัจจุบัน
stevek


9

สิ่งที่แตกต่างจากคำตอบก่อนหน้านี้ทั้งหมด:

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

ยินดีที่ได้เห็นวิธีการที่ไม่ใช้ grep โดยเฉพาะ grep ของฉัน (บน windows) ไม่รองรับตัวเลือก -o
David Roussel

9

คุณสามารถเพิ่ม-Rการค้นหาแบบวนซ้ำ (และหลีกเลี่ยงการใช้ cat) และ-Iละเว้นไฟล์ไบนารี

grep -RIc string .

7

โซลูชั่น AWK แบบบังคับ:

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

ระวังถ้าชื่อไฟล์ของคุณมี ":" อยู่


5

โซลูชัน AWK ซึ่งจัดการชื่อไฟล์รวมถึงโคลอนด้วย:

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

โปรดทราบว่าวิธีนี้ยังไม่พบการเกิดขึ้นหลายครั้งstringในบรรทัดเดียวกัน


4

หากคุณต้องการจำนวนครั้งต่อไฟล์ (ตัวอย่างสำหรับสตริง "tcp"):

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

ตัวอย่างผลลัพธ์:

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

คำอธิบาย:

  • grep -RIci NEEDLE . - ค้นหาสตริง NEEDLE ซ้ำจากไดเรกทอรีปัจจุบัน (ตาม symlink) ละเว้นไบนารีจำนวนการนับจำนวนการเกิดกรณีที่ไม่สนใจ
  • awk ... - คำสั่งนี้จะไม่สนใจไฟล์ที่มีศูนย์เกิดขึ้นและบรรทัดรูปแบบ
  • sort -hr - เรียงลำดับบรรทัดย้อนกลับตามตัวเลขในคอลัมน์แรก

แน่นอนมันทำงานได้กับคำสั่ง grep อื่น ๆ พร้อมตัวเลือก-c(จำนวน) เช่นกัน ตัวอย่างเช่น:

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

3

คุณสามารถใช้วิธีง่าย ๆgrepในการบันทึกจำนวนการเกิดขึ้นอย่างมีประสิทธิภาพ ฉันจะใช้-iตัวเลือกเพื่อให้แน่ใจว่าSTRING/StrING/stringได้รับการบันทึกอย่างถูกต้อง

บรรทัดคำสั่งที่ให้ชื่อไฟล์:

grep -oci string * | grep -v :0

บรรทัดคำสั่งที่ลบชื่อไฟล์และพิมพ์ 0 หากมีไฟล์โดยไม่เกิดขึ้น:

grep -ochi string *

คุณช่วยอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับโซลูชันที่คุณให้ได้ไหม
abarisone

3

ตัวแปรแบบเรียกซ้ำสั้น:

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

1
ขอบคุณ! โซลูชันของคุณใช้ได้กับฉันเท่านั้น (สรุปผลการแข่งขันของไฟล์ทั้งหมด)
Nestor

1

Grep ทางออกเดียวที่ฉันทดสอบด้วย grep สำหรับ windows:

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

วิธีนี้จะนับเหตุการณ์ทั้งหมดแม้ว่าจะมีหลายรายการในหนึ่งบรรทัด -rค้นหาไดเรกทอรีซ้ำ ๆ-oจะ "แสดงเฉพาะส่วนของรูปแบบการจับคู่บรรทัด" - นี่คือสิ่งที่แยกหลาย ๆ เหตุการณ์บนบรรทัดเดียวและทำให้พิมพ์ grep แต่ละคู่ในบรรทัดใหม่; จากนั้นไปป์ผลลัพธ์ที่คั่นด้วยการขึ้นบรรทัดใหม่เหล่านั้นกลับสู่ grep ด้วย-cเพื่อนับจำนวนการเกิดขึ้นโดยใช้รูปแบบเดียวกัน


1

นี่คือ AWK ที่เร็วกว่า grep ทางเลือกในการทำสิ่งนี้ซึ่งจัดการการจับคู่หลายรายการ<url>ต่อบรรทัดภายในชุดของไฟล์ XML ในไดเรกทอรี:

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

วิธีนี้ใช้ได้ดีในกรณีที่ไฟล์ XML บางไฟล์ไม่มีตัวแบ่งบรรทัด


0

Oneliner อื่นที่ใช้ฟังก์ชั่นบรรทัดคำสั่งพื้นฐานการจัดการหลายครั้งต่อบรรทัด

 cat * |sed s/string/\\\nstring\ /g |grep string |wc -l
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.