的标准用法grep
是返回与模式匹配的行。
如果一行可以包含模式的多个匹配项,我如何单独计算每个匹配项,而不是比赛总数?
答案1
该grep
命令有一个-c
重要的选项行数通过模式匹配。由于 的标准用法grep
是返回与模式匹配的行,因此这解决了“计算匹配数”的任务。
如果一行可以包含模式的多个匹配项,如果您想单独计算每个匹配项,则可以使用grep
其非标准选项。-o
这将每个匹配项隔离在其自己的一行上。然后,您可以通过将结果传递给 来计算匹配的数量wc -l
。这用于wc
进行实际计数,而不是grep
。但是,您可以作弊并使用grep -c .
代替 来wc -l
计算从第一个返回的非空行数grep
。由于这有点像黑客,而且wc -l
确实符合我们的要求,因此我们将wc
在下面的示例中使用。
grep
请参阅wc
您的系统的手册。
G
例如:中与模式匹配的行数file
:
$ grep -c -e G file
7
示例:同一文件中的匹配数,但单独计算每个匹配:
$ grep -o -e G file | wc -l
18
答案2
使用awk
:
$ awk '{a += gsub(/pat/,"&"); } END{print a}' file
或者
$ awk '{for(i=1;i<=NF;i++)if ($i ~ /pat/) ++a}END{print a}'
该命令稍微改变了重叠匹配取自这个答案。
$ echo abababa | awk '{ while (a=index($0,"aba")) {++count; $0=substr($0,a+1)}}END{print count}'
答案3
有了perl
,你可以这样做:
perl -lsne '$count++ while m{$regex}g; END{print +$count}' -- -regex='perl regex'
这样做的优点是还可以计算空匹配,例如:
$ seq 10 perl -lsne '$count++ while m{$regex}g; END{print +$count}' -- -regex='\b'
20
(输出的行内容中的 20 个字边界seq 10
)。
使用perl
正则表达式,您还可以使用环视运算符来处理某些重叠匹配的情况:
$ echo abababa | perl -lsne '$count++ while m{$regex}g; END{print +$count}' -- -regex='aba'
2
$ echo abababa | perl -lsne '$count++ while m{$regex}g; END{print +$count}' -- -regex='(?=aba)'
3
它不是匹配 的出现aba
,而是匹配行内aba
可以看到的位置。