计算文件中某个模式的出现次数(即使在同一行上)


94

搜索文件中字符串出现的次数时,通常使用:

grep pattern file | wc -l

但是,由于grep的工作方式,每行仅发现一个事件。我如何搜索字符串出现在文件中的次数,而不管它们是位于同一行还是位于不同行?

另外,如果我要搜索正则表达式模式而不是简单的字符串怎么办?我该如何计算这些,甚至更好地将每个匹配项打印在新行上?

Answers:


156

要计算所有出现的次数,请使用-o。试试这个:

echo afoobarfoobar | grep -o foo | wc -l

man grep当然,(:

更新资料

有些人建议使用grep -co foo而不是grep -o foo | wc -l

别。

此快捷方式并非在所有情况下都有效。手册页说:

-c print a count of matching lines

这些方法的差异如下所示:

1。

$ echo afoobarfoobar | grep -oc foo
1

一旦a{foo}barfoobar行中找到匹配项,搜索就会停止。仅检查了一行并且匹配了该行,因此输出为1。实际上-o在这里被忽略了,您可以使用它grep -c来代替。

2。

$ echo afoobarfoobar | grep -o foo
foo
foo

$ echo afoobarfoobar | grep -o foo | wc -l
2

在(a{foo}bar{foo}bar)行中找到了两个匹配项,因为我们明确要求查找每个匹配项-o)。每次出现都打印在单独的行上,wc -l仅计算输出中的行数。


1
哇...真的那么简单吗?
jrdioko

1
grep -oc在这种情况下不起作用。尝试回显afoobarfoobar | grep -oc foo
Paulus

没有办法对多个文件执行此操作?假设我要查看一组文件中每个文件的出现次数。我可以使用grep -c * 每行执行一次,但不能按实例执行。
基思·泰勒

grep -o foo a.txt b.txt | sort | uniq -c可以正常工作(使用GNU grep):gist.github.com/hudolejev/81a05791f38cbacfd4de3ee3b44eb4f8
hudolejev

2

试试这个:

grep "string to search for" FileNameToSearch | cut -d ":" -f 4 | sort -n | uniq -c

样品:

grep "SMTP connect from unknown" maillog | cut -d ":" -f 4 | sort -n | uniq -c
  6  SMTP connect from unknown [188.190.118.90]
 54  SMTP connect from unknown [62.193.131.114]
  3  SMTP connect from unknown [91.222.51.253]

1

迟来的帖子:在中
使用搜索正则表达式模式作为记录分隔符(RS)。awk
这使您的正则表达式可以用- \n分隔行(如果需要)。

printf 'X \n moo X\n XX\n' | 
   awk -vRS='X[^X]*X' 'END{print (NR<2?0:NR-1)}'

0

Ripgrep是grep的快速替代方案,它刚刚引入了该--count-matches标志,允许对0.9版中的每个匹配进行计数(我使用上面的示例保持一致):

> echo afoobarfoobar | rg --count foo
1
> echo afoobarfoobar | rg --count-matches foo
2

如OP所述,ripgrep也允许使用正则表达式模式(--regexp <PATTERN>)。它还可以在单​​独的行上打印每个(行)匹配项:

> echo -e "line1foo\nline2afoobarfoobar" | rg foo
line1foo
line2afoobarfoobar

-1

修改grep的颜色功能,并计算打印出多少个颜色标签:

echo -e "a\nb  b b\nc\ndef\nb e brb\nr" \
| GREP_COLOR="033" grep --color=always  b \
| perl -e 'undef $/; $_=<>; s/\n//g; s/\x1b\x5b\x30\x33\x33/\n/g; print $_' \
| wc -l
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.