Как выполнять grep для файлов меньше размера и ограничивать расширение

Использование данных вашего примера:

$ 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".

0
04.02.2021, 23:12
1 ответ

Сначала я настрою поддельные данные:

$ 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. (Я уверен, что кто-нибудь оставит комментарий по этому поводу.)

0
18.03.2021, 22:32

Теги

Похожие вопросы