Использование данных вашего примера:
$ grep -Fo 1007 file | wc -l
19
Часть grep
этого конвейера будет искать строку1007
(флаг -F
используется, потому что мы выполняем сравнение строк, а не сопоставление регулярных выражений ). Он будет возвращать каждый отдельный экземпляр строки в новой строке из-за флага -o
. Количество возвращенных строк подсчитывается wc -l
.
Если строка встречается дважды в строке входных данных, она будет подсчитана дважды. Если строка является подстрокой другого слова, она также будет учитываться.
Сawk
:
$ awk -v str="1007" '{ c += gsub(str, str) } END { print c }' file
19
Это подсчитывает количество раз, когда строка встречается с помощьюgsub()
(эта функция возвращает количество раз, когда выполняется замена, и мы применяем ее к каждой строке ввода отдельно )и печатаем общее количество в конце. Интересующая нас строка передается в командной строке с помощью -v str="1007"
.
Сначала я настрою поддельные данные:
$ for fileno in {1..4}; do for line in {1..100000}; do printf "%d,%d,%d,%d,%d,%d,%d,%d\n" $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM; done > ~/tmp/big-fake-${fileno}.csv; done
$ for fileno in {1..4}; do for line in {1..50000}; do printf "%d,%d,%d,%d,%d,%d,%d,%d\n" $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM; done > ~/tmp/small-fake-$fileno.csv; done
Давайте проверим, что у него есть интересующие вас свойства:
$ du -b tmp/*.csv
4528666 tmp/big-fake-1.csv
4529227 tmp/big-fake-2.csv
4529173 tmp/big-fake-3.csv
4528782 tmp/big-fake-4.csv
2263714 tmp/small-fake-1.csv
2264028 tmp/small-fake-2.csv
2264398 tmp/small-fake-3.csv
2265134 tmp/small-fake-4.csv
Теперь поищем какую-нибудь закономерность в файлах меньшего размера:
$ find tmp/ -type f -iregex ".*\.csv" -size -4M -exec grep '1,1,1' {} +
tmp/small-fake-3.csv:15361,2526,13438,1083,3224,13221,1,19248
Естественно grep
здесь может принимать другие флаги, например, -l
, если вас интересуют только имена файлов, которые содержат нужный шаблон.
{} +
вы можете рассматривать как своего рода шаблон для «вставки списка имен файлов, обнаруженных find
вместо квадратных скобок». Так как Grep с удовольствием принимает список имен файлов, а не по одному, это лучше, чем -exec grep '1,1,1' {} \;
, который запускал бы новый экземпляр Grep для каждого отдельного файла, по одному за раз.
Я считаю, что этот -exec
флаг является GNU -измом и недоступен в других типах find
. Я думаю, что на других платформах они идут с шаблоном типа find -print0 | xargs -0
. (Я уверен, что кто-нибудь оставит комментарий по этому поводу.)