如何使用egrep查找包含N次或更多次字符串的文件

时间:2019-01-09 10:37:40

标签: bash awk terminal

我有一个包含约400-500个SQL文件的文件夹,并且需要名称
仅包含3次或多次包含字符串CREATE TABLE的用户。

命令
$ egrep -rl "(CREATE TABLE)" ./*.sql
当然会显示所有文件名,命令
$ egrep -rl "(CREATE TABLE.*){3}" ./*.sql
根本不打印任何东西...

标志:

  • -R –递归
  • -L –匹配文件|仅打印包含匹配项的文件名

5 个答案:

答案 0 :(得分:3)

awk将完成这项工作:

awk 'FNR==1{n=0} /CREATE TABLE/{++n} n>2{print FILENAME; nextfile}' *.sql

答案 1 :(得分:3)

您的命令

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

答案 2 :(得分:2)

能否请您尝试以下。我也在这里处理后端中打开的文件数。

awk 'prev!=FILENAME{n=""}/CREATE TABLE/{++n} n>2{print FILENAME;prev=FILENAME;nextfile}' *.sql

答案 3 :(得分:1)

假设每行可能有多个字符串(仅由Walter A的答案覆盖),这是awk版本(一个支持nextfile的版本)

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

如果您没有GNU grep(根据Walter A的解决方案),也没有nextfile的awk,则可以使用以下解决方案(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来减少计算时间。

答案 4 :(得分:0)

尝试此Perl解决方案

perl -le ' BEGIN { for(glob("*.sql")) { $x=qx(cat $_); $r++ for($x=~m/CREATE TABLE/g); print $_ if $r > 2 ; $r=0 } } '