当每行可能有多个匹配项时,使用 grep 计算匹配项

当每行可能有多个匹配项时,使用 grep 计算匹配项

的标准用法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可以看到的位置。

相关内容