Как подсчитать вхождения слова во всех файлах каталога?

Я пытаюсь подсчитать вхождение определенного слова во всей директории. Это возможно?

Скажем, например, есть каталог со 100 файлами, все файлы которых могут содержать слово «ааа». Как мне подсчитать количество «ааа» во всех файлах в этом каталоге?

Я пробовал что-то вроде:

 zegrep "xception" `find . -name '*auth*application*' | wc -l 

Но это не работает.


person Ashish Sharma    schedule 26.05.2011    source источник


Ответы (7)


grep -roh aaa . | wc -w

Grep рекурсивно просматривает все файлы и каталоги в текущем каталоге в поисках aaa и выводит только совпадения, а не всю строку. Затем просто используйте wc, чтобы подсчитать количество слов.

person Carlos Campderrós    schedule 26.05.2011
comment
Кроме того, если вам не нужны фактические совпадения, а только количество, вы можете использовать grep -rcP '^aaa$' . Это избавит вас от конвейера и предотвратит встраивание «ааа» - person cgledezma; 30.07.2013
comment
@cgledezma хорошая мысль о -c, но она терпит неудачу, если в одной строке есть два или более вхождений searchString. - person Carlos Campderrós; 30.07.2013
comment
ММ... Действительно, я не заметил, что он подсчитывает только количество совпадающих строк, а не фактическое количество совпадений. Тем не менее, я думаю, что может быть полезно установить границы слов, чтобы избежать вложенных совпадений. Извините, неправильно разместил их в предыдущем комментарии: grep -rohP '\baaa\b . | wc -w - person cgledezma; 30.07.2013
comment
@cgledezma конечно, границы слов могут быть полезны в некоторых ситуациях - person Carlos Campderrós; 30.07.2013
comment
В osx решение @cgledezma переводится как grep -rohe '\baaa\b . | wc -w, поскольку -P недоступно. - person IanBussieres; 07.05.2015
comment
Следует также отметить одну вещь: если вы ищете шаблон, в котором есть пробел между несколькими словами или буквами, например, grep -roh 'global \$' . или grep -roh 'one two' . , тогда при передаче по каналу wc -w будут подсчитаны все слова. Таким образом, вы можете захотеть подсчитать только количество точных совпадений, а не общее количество всех слов в результате. Я добился этого, снова подключившись к grep, но ища только первое слово, например, grep -roh 'global \$' . | grep -o 'global' | wc -w . Однако может быть более элегантный способ? - person mrjamesmyers; 06.03.2018

Еще одно решение на основе find и grep.

find . -type f -exec grep -o aaa {} \; | wc -l

Должен правильно обрабатывать имена файлов с пробелами в них.

person Fredrik Pihl    schedule 28.05.2011
comment
идеально! Я использовал поиск по размеру, это работает отлично - person SeanDowney; 29.09.2011
comment
@Fredrik: это работает отлично, но есть ли способ подсчета слов, избегая многократного подсчета этого слова в одном файле? Например: если слово aaa появляется в файле file1.txt 10 раз, но количество должно увеличиваться только на 1, но не на 10, и аналогично в других файлах в каталоге. - person annunarcist; 09.11.2013
comment
@annunarcist - да, это можно сделать. Опубликуйте новый вопрос, и я посмотрю :-) - person Fredrik Pihl; 09.11.2013
comment
@Фредрик: опубликовано! Вот ссылка - person annunarcist; 09.11.2013

Используйте grep самым простым способом. Попробуйте grep --help для получения дополнительной информации.


  1. Чтобы получить количество слов в конкретном файле:

    grep -c <word> <file_name>
    

    Пример:

    grep -c 'aaa' abc_report.csv
    

    Выход:

    445
    

  1. Чтобы получить количество слов во всем каталоге:

    grep -c -R <word>
    

    Пример:

    grep -c -R 'aaa'
    

    Выход:

    abc_report.csv:445
    lmn_report.csv:129
    pqr_report.csv:445
    my_folder/xyz_report.csv:408
    
person Parag Tyagi    schedule 13.03.2016

Давайте использовать AWK!

$ function wordfrequency() { awk 'BEGIN { FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) { word = tolower($i); words[word]++ } } END { for (w in words) printf("%3d %s\n", words[w], w) } ' | sort -rn; }
$ cat your_file.txt | wordfrequency

Здесь указана частота встречаемости каждого слова в предоставленном файле. Если вы хотите увидеть вхождения вашего слова, вы можете просто сделать это:

$ cat your_file.txt | wordfrequency | grep yourword

Чтобы найти вхождения вашего слова во всех файлах в каталоге (нерекурсивно), вы можете сделать следующее:

$ cat * | wordfrequency | grep yourword

Чтобы найти вхождения вашего слова во всех файлах в каталоге (и его подкаталогах), вы можете сделать следующее:

$ find . -type f | xargs cat | wordfrequency | grep yourword

Источник: Ruby AWK-ward

person Sheharyar    schedule 15.12.2014

соедините файлы вместе и выведите результат grep: cat $(find /usr/share/doc/ -name '*.txt') | zegrep -ic '\<exception\>'

если вы хотите, чтобы «исключительный» совпадал, не используйте «\‹» и «\>» вокруг слова.

person jcomeau_ictx    schedule 26.05.2011

Как насчет того, чтобы начать с:

cat * | sed 's/ /\n/g' | grep '^aaa$' | wc -l

как в следующей стенограмме:

pax$ cat file1
this is a file number 1

pax$ cat file2
And this file is file number 2,
a slightly larger file

pax$ cat file[12] | sed 's/ /\n/g' | grep 'file$' | wc -l
4

sed преобразует пробелы в символы новой строки (можно добавить другие символы пробела, например табуляцию, с помощью sed 's/[ \t]/\n/g'). grep просто получает те строки, в которых есть нужное слово, затем wc подсчитывает эти строки для вас.

Теперь могут быть крайние случаи, когда этот сценарий не работает, но он должен быть в порядке для подавляющего большинства ситуаций.

Если вам нужно целое дерево (а не только один уровень каталога), вы можете использовать что-то вроде:

( find . -name '*.txt' -exec cat {} ';' ) | sed 's/ /\n/g' | grep '^aaa$' | wc -l
person paxdiablo    schedule 26.05.2011

Также существует синтаксис регулярного выражения grep только для сопоставления слов:

# based on Carlos Campderrós solution posted in this thread
man grep | less -p '\<'
grep -roh '\<aaa\>' . | wc -l

Для другого синтаксиса регулярного выражения для сопоставления слов см.:

man re_format | less -p '\[\[:<:\]\]'
person tim    schedule 28.05.2011