在搜索文件中出现的字符串数时,我通常使用:
grep pattern file | wc -l
但是,由于grep的工作方式,每行只能找到一个匹配项。如何搜索字符串在文件中出现的次数,无论它们是在相同还是不同的行上?
另外,如果我正在搜索正则表达式模式,而不是简单的字符串,该怎么办?我如何计算这些,或者甚至更好地在新线上打印每场比赛?
答案 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