96

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

grep pattern file | wc -l

但是,由于 grep 的工作方式,这只会在每行中找到一次。如何搜索字符串在文件中出现的次数,无论它们是在同一行还是不同行?

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

4

5 回答 5

162

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

echo afoobarfoobar | grep -o foo | wc -l

当然man grep(:

更新

有些人建议使用 justgrep -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只计算输出中的行数。

于 2010-05-26T12:03:53.433 回答
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]
于 2015-01-29T14:30:44.440 回答
1

迟来的帖子:
使用搜索正则表达式模式作为记录分隔符 (RS),awk
这允许您的正则表达式跨越\n-delimited 行(如果需要)。

printf 'X \n moo X\n XX\n' | 
   awk -vRS='X[^X]*X' 'END{print (NR<2?0:NR-1)}'
于 2012-11-12T22:24:23.433 回答
0

Ripgrep是 grep 的快速替代品,它刚刚在 0.9 版本中引入了--count-matches允许计算每个匹配项的标志(我使用上面的示例来保持一致):

> 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
于 2018-08-15T11:41:49.577 回答
-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
于 2010-05-25T22:05:21.307 回答