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

使用awk打印文件中图案的索引,awk,Awk,我已经在这个上面坐了很长时间了: 我想使用awk在sample.file中搜索模式并打印索引: >sample ATGCGAAAAGATGAACGA GTGACAGACAGACAGACA GATAAACTGACGATAAAA ... 假设我想找到以下模式的索引:“AAAA”(出现两次),所以结果应该是6和51 编辑: 我能够使用以下脚本: cat ./sample.fasta |\ awk '{ s=$0 o=0 m="AAAA" l=length(m)

我已经在这个上面坐了很长时间了:

我想使用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。我总是可以将所有行连接成一行,但也许有一种更优雅的方式


提前感谢

awk
逐行读取文件,这样在多行文件中查找“所有”索引就不会有问题。您的问题是您试图使用
BEGIN
块,顾名思义,它只在程序开始时运行。同样,
index()
函数接受两个参数

对于您的示例数据,这应该适用于:

awk '/AAAA/{print index($0,"AAAA")+l} NR>1{l+=length}' sample.file
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
只有当
AAAA
匹配时,第一个代码块才会运行,第二个代码块在第一个代码块之后的每一行都会运行,并随着该行的长度递增计数器


对于每行有多个匹配项的情况,这应该可以:

awk '/AAAA/{print index($0,"AAAA")+l} NR>1{l+=length}' sample.file
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
awk-v pat=AAAA'BEGIN{for(n=0;n1{while(i=index($0,pat)){print i+l;sub(pat,rep);}l+=length}sample.file
模式作为变量传递;当程序启动时,根据模式的长度生成替换文本。然后循环第一行之后的每一行,获取模式的索引并替换它,以便下一次迭代返回下一个实例


值得一提的是,这两种方法都将匹配
AAAAAA
awk
逐行读取文件,因此查找“全部”不会有问题多行文件中的索引。您的问题是试图使用
BEGIN
块,顾名思义,该块仅在程序开始时运行。此外,
index()
函数还具有两个参数

对于您的示例数据,这应该适用于:

awk '/AAAA/{print index($0,"AAAA")+l} NR>1{l+=length}' sample.file
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
只有当
AAAA
匹配时,第一个代码块才会运行,第二个代码块在第一个代码块之后的每一行都会运行,并随着该行的长度递增计数器


对于每行有多个匹配项的情况,这应该可以:

awk '/AAAA/{print index($0,"AAAA")+l} NR>1{l+=length}' sample.file
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
awk-v pat=AAAA'BEGIN{for(n=0;n1{while(i=index($0,pat)){print i+l;sub(pat,rep);}l+=length}sample.file
模式作为变量传递;当程序启动时,根据模式的长度生成替换文本。然后循环第一行之后的每一行,获取模式的索引并替换它,以便下一次迭代返回下一个实例

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

AWK索引当然:

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

6
51
当然,AWK索引:

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

6
51

如果您对基于零的索引没有问题,这可能会更简单

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

5:AAAA
50:AAAA

假设标题行已过帐,如果不使用remove
sed
命令。请注意,这假设为单字节字符,如图所示。对于扩展字符集,它将不是字符位置,而是字节偏移量。

如果对基于零的索引没有问题,这可能会更简单

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

5:AAAA
50:AAAA

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

您现在提交的代码是针对只搜索一行的情况编写的。您现在提交的代码是为在这种情况下,您只搜索一行。
sed 1d sample.fasta | tr-d'\n'| grep-ob AAAA
然后我得到
0:AAAA AAAA
有些错误,但是我在上面的注释中使用了您的
sed
部分使它们工作起来。谢谢!
awk-F:{print$1+1}“
sed 1d sample.fasta | tr-d'\n'| grep-ob AAAA
然后我得到了
0:AAAA AAAA
一些错误,但是我在上面的评论中使用了你的
sed
部分使它们工作起来。谢谢!
awk-F:{print$1+1}
工作得很有魅力,但是我不得不添加sed 1d dna.txt{awk'{your code}”'为了忽略第一行标题中的字符。效果很好,但是我不得不添加sed 1d dna.txt | awk'{your code}'来忽略第一行标题中的字符。效果很好。虽然我现在不需要它,但我想知道您如何精确匹配“AAAA”如果没有查找AAAA的模式,您只需使用类似于
[^a]AAAA[^a]
的模式,然后重新编写代码以接受正则表达式搜索而不是字符串搜索。(
index()
无法搜索正则表达式。)只是更新了它以跳过第一行,我没有意识到它是数据的一部分。工作得很好。虽然我现在不需要它,但我想知道,如果不找到AAAA的模式,您将如何精确匹配“AAAA”?您只需使用像
[^a]AAAA[^a]
这样的模式,然后重新编写代码以接受正则表达式搜索而不是字符串搜索。(
index()
无法搜索正则表达式。)只是将其更新为跳过第一行,我没有意识到它是数据的一部分。