Bash 如何计算多个重叠字符串并获得每行(awk或其他任何内容)的总出现次数

Bash 如何计算多个重叠字符串并获得每行(awk或其他任何内容)的总出现次数,bash,awk,substr,Bash,Awk,Substr,我有这样一个输入文件: 315secondbin x12121321211332123x 315firstbin 3212212121x 315thirdbin 132221312 316firstbin 121 316secondbin 1212 我想做的是计算在每行计数重叠中存在几个不同字符串(比如“121”和“212”)的实例数。因此,我的预期输出是: 6 5 0 1 2 因此,我稍微修改了另一个线程中的一些awk,以使用OR运算符,希望它能够计算满足任一条件的所有内容:

我有这样一个输入文件:

315secondbin    x12121321211332123x
315firstbin 3212212121x
315thirdbin 132221312
316firstbin 121
316secondbin    1212
我想做的是计算在每行计数重叠中存在几个不同字符串(比如“121”和“212”)的实例数。因此,我的预期输出是:

6
5
0
1
2
因此,我稍微修改了另一个线程中的一些awk,以使用OR运算符,希望它能够计算满足任一条件的所有内容:

{
count = 0
$0 = tolower($0)
while (length() > 0) {
    m = match($0, /212/ || /121/)
    if (m == 0)
         break
    count++
    $0 = substr($0, m + 1)
}
print count
}
不幸的是,我的输出是:

8
4
0
2
3
但如果我不考虑这个问题,或者它很重要。我做错了什么

另外,我通过运行以下命令在文件ymaz.txt上运行脚本:

 cat ymaz.txt | awk -v "pattern=" -f count3.awk
作为替代方法,我尝试了以下方法:

{
count = 0
$0 = tolower($0)
while (length() > 0) {
    m = match($0, /212/)
y = match($0, /121/)
    if ((m == 0) && (y == 0))
         break
    count++
    $0 = substr($0, (m + 1) + (y + 1))
}
print count
}
但我的结果是:

1
1
0
1
1
我做错了什么?我知道我应该理解代码,而不是把东西剪切粘贴在一起,但这是我目前的技能水平


顺便说一句,当我没有OR时(即我只是在搜索一个字符串),它工作得非常完美。

你把它弄得太复杂了:

{
    count=0
    while ( match($0,/121|212/) ) {
        count++
        $0=substr($0,RSTART+1)
    }
    print count
}

$ awk -f tst.awk file
6
5
0
1
2
您的基本问题是将条件与regexp混淆。一个regexp可以与一个字符串进行比较以形成一个条件,当所讨论的字符串是$0时,您可以省略它,只使用
regexp
作为
$0~regexp
的简写,但在这种情况下,所测试的仍然是一个条件。match()的第二个参数是regexp,而不是条件
|
是regexp中的
运算符,而
|
是条件中的
运算符
/…/
是regexp分隔符

/foo/
是一个regexp

$0~/foo/
是一个条件

条件上下文中的
/foo/
$0~/foo/
的缩写,但在任何其他上下文中都只是一个regexp

在条件上下文中,
/foo/| | |/bar
$0~/foo/| |$0~/bar/
的简写,但作为第二个要匹配的参数()awk实际上假定您打算编写:

match($0,($0 ~ /foo/ || $0 ~ /bar/))
i、 它将根据foo或bar测试当前记录,如果为true,则该条件的计算结果为1,然后将1作为第二个参数指定给match()

看:

获取Arnold Robbins的《有效的Awk编程》,第四版。

Perl方法:

perl -lpe '$_ = () = m/(?=121|212)/go'
输出:

6
5
0
1
2

是不是应该是
/(212)|(121)/
?我在第一行计算了6个匹配项,第二行计算了5个匹配项!你应该把它作为一个答案@ooga!哈哈,好吧,我修正了预期输出。这就是为什么我要写一个脚本,因为当我尝试数数的时候,我的视力不好。哈哈哈,你是对的,ooga,我的预期输出也是错误的(这就是为什么我需要自动完成任务)。我已更正了预期输出。更重要的是,你的修正修正了它,我不理解那些斜杠是如何工作的。最后一个工作脚本是:
{count=0$0=tolower($0),而(length()>0){m=match($0,/212 | 121/)if(m==0)break count++$0=substr($0,m+1)}print count}
Ooga的第一条评论应该标记为答案,谢谢!多亏了这个帖子里的好人,我们节省了很多时间。
6
5
0
1
2