【发布时间】:2015-06-04 01:05:15
【问题描述】:
我正在尝试计算重复字符串的出现次数。例如。
echo 'joebobtomtomtomjoebobmike' | grep -o 'tomtom' | wc -l
这输出 1,但显然字符串 'tomtom' 在这里适合两次。我怎样才能让它计算两次出现的次数?
谢谢!
【问题讨论】:
-
完成了!谢谢。您的回答和 potong 都有效地回答了我的问题。
我正在尝试计算重复字符串的出现次数。例如。
echo 'joebobtomtomtomjoebobmike' | grep -o 'tomtom' | wc -l
这输出 1,但显然字符串 'tomtom' 在这里适合两次。我怎样才能让它计算两次出现的次数?
谢谢!
【问题讨论】:
你可以使用这个 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。
【讨论】:
tolower() 将$0 转换为小写。另请注意,我通过使用变量pattern 使脚本更具可移植性,您将其作为选项传递给脚本。
这可能对你有用(GNU sed):
sed -r '/(tom)\1/!d;:a;s//\n\1/;ta;s/\n//'| wc -l
重复模式tomtom 可以用正则表达式形式重写为(tom)\1,然后用换行符替换重复模式的第一部分并循环直到找不到更多模式,这将给出表示重叠模式的行数。在打印结果时,必须考虑这一点并从结果中减去,即必须删除最后一个(在这种情况下是第一个)换行符。当然,如果没有重复模式,则结果必须为零,因此第一个 sed 命令。
【讨论】:
:b;$!{N;bb};s/\n//g; 将整个文件啜饮到内存中
你可以遍历字符串的长度,看看当前位置的子字符串是否是所需的文本:
string=joebobtomtomtomjoebobmiketomtomtom
match=tomtom
for ((i=0; i <= ${#string} - ${#match}; i++)); do
[[ ${string:i:${#match}} == $match ]] && ((count++))
done
echo $count # => 4
【讨论】: