grep按行显示模式出现的次数

4

从输入文件中:

I am Peter
I am Mary
I am Peter Peter Peter
I am Peter Peter

我希望输出结果像这样:


1 I am Peter
3 I am Peter Peter Peter
2 I am Peter Peter

在这里,1、3和2是“Peter”的出现次数。

我尝试了这个,但是信息的格式不符合我的要求:

grep -o -n Peter inputfile

你要搜索的字符串是一个简单的字符串吗?(或者你使用正则表达式运算符,如 |* 或括号 ())。如果你搜索 pepe,而你有类似于 pepepe 的东西,那么出现次数是多少呢?(它算作一次出现还是两次出现) - Luis Colorado
2个回答

10

这不是用 grep 轻松解决的,我建议将其升级到 awk

awk '$0 ~ FS { print NF-1, $0 }' FS="Peter" inputfile

输出:

1 I am Peter
3 I am Peter Peter Peter
2 I am Peter Peter

###编辑

回答评论中的问题:

如果我想不区分大小写怎么办?如果我想使用多个模式,例如“Peter | Mary | Paul”,那么“我是Peter peter pAul Mary marY John”将得到5的计数吗?

如果您正在使用GNU awk,则可以通过启用IGNORECASE并将模式设置在FS中来实现,方法如下:

awk '$0 ~ FS { print NF-1, $0 }' IGNORECASE=1 FS="Peter|Mary|Paul" inputfile

输出:

1 I am Peter
1 I am Mary
3 I am Peter Peter Peter
2 I am Peter Peter
5 I am Peter peter pAul Mary marY John

这里至少有 500,000 行代码,性能是 awk 的一个问题,这是通过 Perl 的系统调用实现的。 - Cindy Turlington
1
@CindyTurlington:这很高效,我不确定你是否可以通过grep使其更加高效。根据您使用的awk版本,您可能可以通过切换到“nawk”或“mawk”使其快一个数量级。 - Thor
使用 LC_ALL=A 在 awk 前面,看起来速度要快得多。 - Cindy Turlington
@CindyTurlington:肯定是 LC_ALL=C 吧? - Thor
@CindyTurlington:使用GNU awk,这将是直截了当的,参见编辑。 - Thor
显示剩余2条评论

0

你不需要使用-o-n。从grep --help中得知:

  -o, --only-matching       show only the part of a line matching PATTERN
  ...
  -n, --line-number         print line number with output lines

删除它们,你的输出将会更好。我认为你误解了-n的含义——它只显示行号,而不是出现次数。

看起来你想要获取每行“Peter”出现的次数。你需要使用不止一个grep命令。可以考虑使用awk。或者你可以循环遍历每一行,将其拆分成单词(比如一个数组),并对每一行的数组使用grep -c,以打印该行的计数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接