使用sed或grep在一行中计算正则表达式模式匹配的数量?

31

我想要计算单行(或所有行,因为通常只有一行)中匹配的数量。

我想要计算不仅是每行的一个匹配项,如下所示:

echo "123 123 123" | grep -c -E "123" # Result: 1
更好的例子:
echo "1 1 2 2 2 5" | grep -c -E '([^ ])( \1){1}' # Result: 1, expected: 2 or 3

数据是否总是以空格分隔? - Mike Pennington
永远只会有“一个数据”,因为也许我想在“123 123 123 123”中匹配3(或2)次的“123 123”。 - Tyilo
1
给问题+1,给奇怪的正则表达式示例-1。 - Mike Pennington
5个回答

53
你可以使用 grep -o, 然后将结果通过管道传送到 wc -l:
$ echo "123 123 123" | grep -o 123 | wc -l
3

1
我的版本的 grep 不知道 -o 是什么 :( - manojlds
15
你需要今年向圣诞老人要一个新的 grep。 :) - Simon Whitaker
@manojlds,你有egrep吗?同样的事情也可以用egrep完成。 - Mike Pennington
如果不在结尾加上管道符号和 wc -l 命令,你就可以看到它们的输出。 - Simon Whitaker
你的grep -E示例还是我对你问题的回答导致结果为2?(前者得到5,后者得到3。) - Simon Whitaker
显示剩余5条评论

1

也许你应该先将空格转换为换行符:

$ echo "1 1 2 2 2 5" | tr ' ' $'\n' | grep -c 2
3

1

可能是下面这样:

echo "123 123 123" | sed "s/123 /123\n/g" | wc -l

(可能有点丑陋,但我的bash技能还不够好)


@Tyilo - 你尝试了什么?我得到了上面输入的3。 - manojlds
我复制并粘贴了你的代码,但我现在记得我的sed不支持\n - Tyilo

0
为什么不使用 awk 呢?您可以使用 awk '{print gsub(your_regex,"&")}' 在每行中打印匹配的次数,或者使用 awk '{c+=gsub(your_regex,"&")}END{print c}' 打印总匹配次数。请注意,相对速度可能因使用的 awk 实现和输入而异。

另一种使用gawk的方法是 gawk -v FPAT=your_regex '{print NF}'gawk -v FPAT=your_regex '{c+=NF}END{print c}' - jarno

0

这个可能适合你:

sed -n -e ':a' -e 's/123//p' -e 'ta' file | sed -n '$='

GNU sed 可以这样编写:

sed -n ':;s/123//p;t' file | sed -n '$='

第一个脚本在GNU sed 4.2.2中无法工作:“sed: can't find label for jump to `a'”。如果您将“:ta”替换为“:a”,则似乎可以更好地工作。此外,该脚本似乎需要输入末尾的换行符。另外,如果没有找到匹配项,则该脚本不会输出任何内容。测试:“printf 123 | sed -n ':;s/123//p;t' | sed -n '$='”不会输出任何内容。 - jarno

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