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

时间:2010-05-25 21:44:52

标签: search count grep match

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

grep pattern file | wc -l

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

另外,如果我正在搜索正则表达式模式,而不是简单的字符串,该怎么办?我如何计算这些,或者甚至更好地在新线上打印每场比赛?

5 个答案:

答案 0 :(得分:147)

要计算所有出现次数,请使用-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 :(得分: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]

答案 2 :(得分:1)

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

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

答案 3 :(得分: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

答案 4 :(得分:-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