Как найти файлы, содержащие строку N раз или чаще, используя egrep - PullRequest
0 голосов
/ 09 января 2019

У меня есть папка с 400-500 SQL-файлами и мне нужны имена
только те, которые содержат строку CREATE TABLE 3 раза или чаще.

Пока команда
$ egrep -rl "(CREATE TABLE)" ./*.sql
выводит мне конечно все имена файлов, команда
$ egrep -rl "(CREATE TABLE.*){3}" ./*.sql
не печатает вообще ...

Флаги:

  • -R & ndаsh; рекурсивный
  • -L & ndash; файлы с совпадениями | печатать только имена файлов, содержащих совпадения

Ответы [ 5 ]

0 голосов
/ 09 января 2019

Предполагая возможность наличия нескольких строк в строке (только в ответе Walter A ), вот его версия awk (та, которая поддерживает nextfile)

awk '(FNR==1){n=0}
     {n+=split($0,a,/CREATE TABLE/)-1}
     (n>2) {print FILENAME; nextfile}' */.sql

Если у вас нет GNU grep (согласно решению Вальтера А) и у вас нет awk с nextfile, можно использовать следующие решения (POSIX):

awk '(FNR==1){n=0; p=1}
     p {n+=split($0,a,/CREATE TABLE/)-1}
     (n>2) && p {print FILENAME; p=0}' */.sql

Разница между этими двумя решениями:

  • Решение 1 не будет обрабатывать полный файл, поскольку при выполнении условия будет создано досрочное завершение для каждого файла.
  • Решение 2 не может выполнить такое действие, однако мы можем сократить вычислительное время, избегая split, если условие выполняется.
0 голосов
/ 09 января 2019

Ваша команда

egrep -rl "(CREATE TABLE.*){3}" ./*.sql

ищет 3 CREATE TABLE в одной строке. Когда они находятся на разных линиях, вам нужно сделать что-то другое, и когда у вас есть GNU grep, вам повезло: у него есть опция -z.

# minimal change of your command
egrep -zrl "(CREATE TABLE.*){3}" ./*.sql
# moving option E to the options as suggested by @anubhava
grep -zErl "(CREATE TABLE.*){3}" ./*.sql
0 голосов
/ 09 января 2019

Не могли бы вы попробовать следующее. Я тоже забочусь о количестве открытых файлов в бэкэнде.

awk 'prev!=FILENAME{n=""}/CREATE TABLE/{++n} n>2{print FILENAME;prev=FILENAME;nextfile}' *.sql
0 голосов
/ 09 января 2019

Попробуйте это решение Perl

perl -le ' BEGIN { for(glob("*.sql")) { $x=qx(cat $_); $r++ for($x=~m/CREATE TABLE/g); print $_ if $r > 2 ; $r=0 } } '
0 голосов
/ 09 января 2019

Это awk сделает работу:

awk 'FNR==1{n=0} /CREATE TABLE/{++n} n>2{print FILENAME; nextfile}' *.sql
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...