使用awk打印文件中图案的索引

时间:2018-11-06 21:29:37

标签: awk

我已经坐了很久了:

我想使用awk在sample.file中搜索模式并打印索引:

>sample
ATGCGAAAAGATGAACGA
GTGACAGACAGACAGACA
GATAAACTGACGATAAAA
...

假设我要查找以下模式的索引:“ AAAA”(出现两次),因此结果应为6和51。

编辑:

我能够使用以下脚本:

cat ./sample.fasta |\
awk '{
    s=$0
    o=0
    m="AAAA"
    l=length(m)
    i=index(s,m)
    while (i>0) {
        o+=i
        print o
        s=substr(s,i+l)
        o+=l-1
        i=index(s,m)
    }
}'

但是,它会在每条新行上重新启动索引,因此结果为6和15。我总是可以将所有行连接为一行,但是也许有一种更优雅的方法。

预先感谢

3 个答案:

答案 0 :(得分:1)

awk逐行读取文件,因此在多行文件中查找“所有”索引永远不会成为问题。您的问题是,您正在尝试使用BEGIN块,顾名思义,该块仅在程序的开头运行。同样,index()函数接受两个参数。

对于您的示例数据,这应该可以工作:

awk '/AAAA/{print index($0,"AAAA")+l} NR>1{l+=length}' sample.file

仅当AAAA匹配时,第一段代码才运行,第二段代码在第一行之后的每一行运行,并以该行的长度递增计数器。


对于每行有多个匹配项的情况,这应该起作用:

awk -v pat=AAAA 'BEGIN{for(n=0;n<length(pat);n++) rep=rep"x"} NR>1{while(i=index($0,pat)){print i+l; sub(pat,rep);} l+=length}' sample.file

模式作为变量传递;程序启动时,将根据图案的长度生成替换文本。然后循环遍历第一行之后的每一行,获取模式的索引并替换它,以便下一次迭代返回下一个实例。

值得一提的是,这两种方法都将与AAAAAA相匹配。

答案 1 :(得分:1)

AWK索引当然是

awk '{ l=index($0, "AAAA"); if (l) print l+i; i+=length(); }' dna.txt

6
51

答案 2 :(得分:0)

如果您满意从零开始的索引,这可能会更简单。

$ sed 1d file | tr -d '\n' | grep -ob AAAA

5:AAAA
50:AAAA

假定标题行已发布,如果未删除sed命令。请注意,这假设如图所示为单字节字符。对于扩展字符集,它不是字符位置,而是字节偏移量。