Посчитайте все вхождения строки во множестве файлов с помощью grep - PullRequest
280 голосов
/ 16 декабря 2008

У меня есть куча файлов журналов. Мне нужно выяснить, сколько раз строка встречается во всех файлах.

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.)

Ответы [ 15 ]

288 голосов
/ 14 июля 2010

Это работает для нескольких вхождений в строке:

grep -o string * | wc -l
284 голосов
/ 16 декабря 2008
cat * | grep -c string
27 голосов
/ 27 февраля 2013
grep -oh string * | wc -w

будет считать несколько вхождений в строке

20 голосов
/ 16 декабря 2008

Вместо использования -c, просто передайте его по каналу wc -l.

grep string * | wc -l

Это перечислит каждое вхождение в одной строке, а затем подсчитает количество строк.

Это будет пропускать случаи, когда строка встречается 2+ раза в одной строке.

15 голосов
/ 16 декабря 2008
cat * | grep -c string

Одно из редких полезных приложений cat.

9 голосов
/ 27 февраля 2013

Что-то отличное от всех предыдущих ответов:

perl -lne '$count++ for m/<pattern>/g;END{print $count}' *
7 голосов
/ 12 декабря 2013

Вы можете добавить -R для рекурсивного поиска (и избегать использования cat) и -I для игнорирования двоичных файлов.

grep -RIc string .
6 голосов
/ 29 сентября 2011

Обязательное решение AWK:

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

Будьте осторожны, если в именах ваших файлов есть ":".

5 голосов
/ 26 января 2013

Решение AWK, которое также обрабатывает имена файлов, включая двоеточия:

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

Имейте в виду, что этот метод все еще не находит несколько вхождений string в одной строке.

4 голосов
/ 30 апреля 2018

Если вы хотите количество вхождений в файл (пример для строки "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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...