我有一个这样的输入文件:
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
但是,如果我遗漏OR,它就完全算了。我做错了什么?
另外,我通过运行:
在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时(即我只是搜索1个字符串),它完美无缺。答案 0 :(得分:3)
你太复杂了:
{
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
你的根本问题是你正在使用正则表达式混淆一个条件。可以将正则表达式与字符串进行比较以形成条件,当有问题的字符串为$ 0时,您可以将其保留,只使用regexp
作为$0 ~ regexp
的简写,但在该上下文中是什么&#39被测试仍然是一个条件。 match()的第二个arg是正则表达式,而不是条件。 |
是正则表达式中的or
运算符,而||
是条件中的or
运算符。 /.../
是正则表达式分隔符。
/foo/
是正则表达式
$0 ~ /foo/
是一个条件
/foo/
是$0 ~ /foo/
的简写,但在任何其他上下文中只是一个正则表达式。
/foo/ || /bar
是$0 ~ /foo/ || $0 ~ /bar/
的简写,但是作为匹配()的第二个参数,awk实际上假定您打算写:
match($0,($0 ~ /foo/ || $0 ~ /bar/))
即。它将针对foo或bar测试当前记录,如果为true,则该条件的计算结果为1,然后将该1赋予match(),因为它是第二个arg。
查找
$ echo foo | gawk 'match($0,/foo/||/bar/)'
$ echo foo | gawk '{print /foo/||/bar/}'
1
$ echo 1foo | gawk 'match($0,/foo/||/bar/)'
1foo
获取由Arnold Robbins撰写的Effective Awk Programming,4th Edition。
答案 1 :(得分:3)
Perl方式:
perl -lpe '$_ = () = m/(?=121|212)/go'
输出:
6
5
0
1
2