Порахуйте всі входження рядка у великій кількості файлів із грепом


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, я хочу повернутися назад.)


1
Чи можете ви сказати мені, що робить grep -v: 0? . Я знаю, що він рахується для файлів із випадками, що перевищують 0. Що означає опція -v та: 0 означає ?. Будь ласка, дайте мені знати.
Готем Хонавара

@GauthamHonnavara grep: 0 шукає рядок, який відповідає рядку: 0. -v - це можливість інвертувати цей пошук, тому замість цього використовується grep -v: 0 означає знайти всі рядки, які не містять: 0, так що рядки з file4: 5 та file27: 193 проходили б через те, що вони не містять: 0
пінгвін359

Ви можете вибрати кілька файлів, використовуючи пробіл. grep file1 file2 --options
Днянешвар Харер

Відповіді:


288
cat * | grep -c string

9
Це таке ж обмеження, що воно рахує кілька випадків в одному рядку лише один раз. Я здогадуюсь, що така поведінка в цьому випадку нормальна.
Майкл Харен

@Michael Haren Так, у рядку може бути лише одне виникнення рядка.
Желько Філіпін

2
Я вважаю за краще зробити grep -c string<*так, просто замінивши простір на менше.
JamesM-SiteGen

48
Не стосується кількох випадків на лінії
блюзмен

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.
кодер

2
grep -ioR string * | wc -lце те, що я використовую для нечутливого до
рецидиву

2
У цьому відображаються відповідні файли, а потім загальна кількість матчів:grep -rc test . | awk -F: '$NF > 0 {x+=$NF; $NF=""; print} END{print "Total:",x}'
Ярон

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, esp, оскільки мій греп (у Windows) не підтримує опцію -o.
Девід Руссель

9

Ви можете додавати -Rдо пошуку рекурсивно (і уникати використання кота) та -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 рекурсивно з поточного каталогу (наступні посилання), ігноруючи бінарні файли, рахуючи кількість подій, ігноруючи регістр
  • awk ... - ця команда ігнорує файли з нульовими входженнями та форматами рядків
  • sort -hr - сортує рядки у зворотному порядку за номерами у першому стовпці

Звичайно, він також працює з іншими командами grep з опцією -c(count). Наприклад:

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 *

Чи можете ви детальніше розглянути свою відповідь, додавши трохи більше опису про рішення, яке ви надаєте?
абарізон

3

короткий рекурсивний варіант:

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

1
Дякую! На мене працювало лише ваше рішення (підсумовував збіги всіх файлів).
Нестор

1

Рішення єдиного грепу, яке я протестував із грепом для windows:

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

Це рішення порахує всі випадки, навіть якщо їх в одному рядку декілька. -rрекурсивно здійснює пошук у каталозі, -o"показуватиме лише ту частину рядка, що відповідає PATTERN" - це те, що розбиває кілька випадків на одному рядку і робить греп друк кожної відповідності в новому рядку; потім передайте ці результати, розділені новим рядком, назад у греп, -cщоб порахувати кількість подій, використовуючи той самий шаблон.


1

Ось більш швидкий альтернативний спосіб AWK, який обробляє декілька збігів по <url>рядку в колекції XML-файлів у каталозі:

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

Це добре працює у випадках, коли у деяких файлах XML немає розривів рядків.


0

Ще один ліній, що використовує основні функції командного рядка, що обробляють кілька випадків на рядок.

 cat * |sed s/string/\\\nstring\ /g |grep string |wc -l
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.