使用grep / linux / bash计算重复字符串的重叠出现次数

时间:2015-06-04 01:05:16

标签: linux bash shell sed grep

我正在尝试计算重复字符串的出现次数。例如

echo 'joebobtomtomtomjoebobmike' | grep -o 'tomtom' | wc -l

这输出1,但显然字符串'tomtom'在这里适合两次。我怎样才能使它同时计算两次出现?

谢谢!

3 个答案:

答案 0 :(得分:3)

您可以使用此awk脚本

{
    count = 0
    $0 = tolower($0)
    while (length() > 0) {
        m = match($0, pattern)
        if (m == 0)
             break
        count++
        $0 = substr($0, m + 1)
    }
    print count
}

<强>解释

我们首先将该行转换为全部小写以忽略大小写。此脚本通过在匹配模式后缩短字符串来工作。它使用函数match()来查找pattern匹配的位置。如果 m == 0,这意味着没有找到匹配项,因此我们可以摆脱循环。我们在循环的每次迭代中递增count,然后将$0字符串重置为从索引m + 1开始的子字符串。

如果将其保存为a.awk,则可以执行

echo "joebobtomtomtomjoebobmike" | awk -v "pattern=tomtom" -f a.awk 

它将输出2

答案 1 :(得分:1)

这可能适合你(GNU sed):

sed -r '/(tom)\1/!d;:a;s//\n\1/;ta;s/\n//'| wc -l

重复模式tomtom可以用regexp形式重写为(tom)\1,然后用换行符替换重复模式的第一部分并循环,直到找不到更多模式将给出一些行指示重叠的模式。打印结果必须考虑并从结果中减去,即必须删除最后一个(在这种情况下是第一个)换行符。当然,如果没有重复模式,结果必须为零,因此第一个sed命令。

答案 2 :(得分:1)

你可以走一下字符串的长度,看看当前位置的子字符串是否是所需的文字:

string=joebobtomtomtomjoebobmiketomtomtom
match=tomtom
for ((i=0; i <= ${#string} - ${#match}; i++)); do
    [[ ${string:i:${#match}} == $match ]] && ((count++))
done
echo $count   # => 4