将字符附加到multifasta文件中特定行的末尾

时间:2012-10-09 09:23:02

标签: perl sed awk grep

我有一个带有配对末尾读取的multifasta文件,这样彼此相邻的是配对(它们具有相同的读取名称)。我想在整个文件中分别将“/ 1”和“/ 2”附加到第一次和第二次读取。我不知道文件中有多少次读取。以下是文件的外观(为了清晰起见,在读取之间添加空行):

  

HWI-ST1018:1:1101:10007:34134#0   ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTT   CCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG

     

HWI-ST1018:1:1101:10007:34134#0   GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAG   GAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG

     

HWI-ST1018:1:1101:10016:6488#0   ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAG   AAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA

     

HWI-ST1018:1:1101:10016:6488#0   TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTC   CTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC

这就是我希望它出现的方式:

  

HWI-ST1018:1:1101:10007:34134#0/1   ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTT   CCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG

     

HWI-ST1018:1:1101:10007:34134#0/2   GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAG   GAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG

     

HWI-ST1018:1:1101:10016:6488#0/1   ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAG   AAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA

     

HWI-ST1018:1:1101:10016:6488#0/2   TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTC   CTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC

然后我将grep它,删除“ - ”分隔符并保存正向读取(即以“/ 1”结尾的那些)和反向读取(即以“/ 2”结尾的那些)在不同的文件中如下:

grep -A 2 "/1" filename.fa | sed '/--/d' > reads_1.fa
grep -A 2 "/2" filename.fa | sed '/--/d' > reads_2.fa

我认为这可以用sed和awk完成,但我还没弄明白怎么做。请帮忙。提前致谢。

6 个答案:

答案 0 :(得分:2)

使用sed生成中间文件:

#!/bin/sed -f

1 {
    x
    s/^$/\\1/
    x
}
/^HWI/ {
    G
    s/\n//
    x
    y/12/21/
    x
}

单行:

sed -e '1{x;s/^$/\\1/;x};/^HWI/{G;s/\n//;x;y/12/21/;x}'

命令非常简单。在第一对括号中分组的命令是为第一行执行的,它们用\1初始化保持空间(辅助缓冲区)。为此,我们使用x exchange命令将模式空间(工作缓冲区)的内容与保留空间的内容交换。然后我们用\1替换空行,然后再次交换空格。

对于以HWI开头的每一行,都会执行分组在第二对括号中的命令。首先,我们将保持空间的内容附加到模式空间中。因为它是以换行符开头附加的,所以下一个命令会将其删除。现在我们必须将数字从1交换为2,从2交换为1.首先我们再次交换空格的内容,然后使用y命令交换字符。它定义了当找到1或2时,它们必须分别用2或1替换。最后,我们恢复空格的内容。

您还可以编写单个脚本来执行所有操作,将它们分隔到文件中:

#!/bin/sed -f

/^HWI/! d

:start_forward
s/$/\\1/

:forward
w reads_1.fa
n
/^HWI/! b forward

s/$/\\2/

:reverse
w reads_2.fa
n
/^HWI/! b reverse

b start_forward

以较短的形式:

sed -e '/^HWI/!d;:s;s/$/\\1/;:f;wreads_1.fa
    n;/^HWI/!bf;s/$/\\2/;:r;wreads_2.fa
    n;/^HWI/!br;bs'

这里我们首先忽略所有行,直到找到以HWI开头的行。然后我们必须循环,一个用于写入前向数据,另一个用于后向数据。在循环之间存在用于在将行写入相应文件之前附加相应的\1\2的命令。循环是类似的,它们简单地将行写入它们各自的文件,从输入加载一个新行并检查它是否是以HWI开头的行,表明它应该转到下一个循环。

更彻底的解释:

当行不以HWI开头时执行第一个命令(我们通过在其后面添加!否定匹配)。命令为d以删除一行,并强制sed加载下一行并重新启动脚本。实际上,我们循环直到找到以HWI开头的字符串。

现在,我们使用:命令来定义名为start_forward的标签。标签只不过是脚本中我们可以跳转到的位置的名称。如果我们继续在标签之间跳转并且永远不会到达脚本的末尾,我们最终将永远不会重新启动脚本,因此第一个命令永远不会在找到以HWI开头的第一行之后执行。我们要做的第一件事就是将\1追加到行尾。

现在我们定义一个名为forward的新标签,当我们遍历这些线时,它将用于跳回。循环非常简单,首先我们使用reads_1.fa命令将当前行写入相应的文件w,然后我们使用n行将下一行读入模式空间,并且最后,我们检查新读取的行是否以HWI开头。如果没有,我们执行b分支命令跳回forward标签,允许我们开始循环的另一次迭代。

如果行以HWI开头,我们现在必须转到另一个循环。在此之前,我们必须在\2附加一行。循环类似于前一个循环,除了当我们在找到另一个HWI行时退出循环时,我们必须使用start_forward命令分支回b标签,以便切换回上一个循环。

希望这有助于=)

答案 1 :(得分:1)

这会将/0/1添加到读取:

perl -pe 'if (/#0/) { $x = 1 - $x; s:#0:#0/$x: }'

答案 2 :(得分:1)

awk one-liner:

 awk -F'#' 'NF==2{a[$1]=($1 in a)?++a[$1]:1;$0=$0"/"a[$1];}1' file

<强>测试

kent$  cat t.txt
HWI-ST1018:1:1101:10007:34134#0
ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTT 
CCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG

HWI-ST1018:1:1101:10007:34134#0
GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAG 
GAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG

HWI-ST1018:1:1101:10016:6488#0
ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAG 
AAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA

HWI-ST1018:1:1101:10016:6488#0
TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTC 
CTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC

kent$  awk -F'#' 'NF==2{a[$1]=($1 in a)?++a[$1]:1;$0=$0"/"a[$1];}1' t.txt
HWI-ST1018:1:1101:10007:34134#0/1
ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTT 
CCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG

HWI-ST1018:1:1101:10007:34134#0/2
GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAG 
GAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG

HWI-ST1018:1:1101:10016:6488#0/1
ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAG 
AAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA

HWI-ST1018:1:1101:10016:6488#0/2
TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTC 
CTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC

答案 3 :(得分:1)

awk 'BEGIN{i=1}{if($0~/#0/){print $0"/"i;if(i==1)i=2;else i=1;}else {print}}' your_file

测试如下:

> cat temp
>HWI-ST1018:1:1101:10007:34134#0
ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTT
CCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG
>HWI-ST1018:1:1101:10007:34134#0
GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAG
GAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG
>HWI-ST1018:1:1101:10016:6488#0
ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAG
AAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA
>HWI-ST1018:1:1101:10016:6488#0
TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTC
CTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC

执行:

> awk 'BEGIN{i=1}{if($0~/#0/){print $0"/"i;if(i==1)i=2;else i=1;}else {print}}' temp
>HWI-ST1018:1:1101:10007:34134#0/1
ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTT
CCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG
>HWI-ST1018:1:1101:10007:34134#0/2
GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAG
GAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG
>HWI-ST1018:1:1101:10016:6488#0/1
ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAG
AAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA
>HWI-ST1018:1:1101:10016:6488#0/2
TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTC
CTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC
> 

答案 4 :(得分:1)

你有一个叫做洗牌的multifasta。您可以使用GNU awk取消预览并创建两个文件。请注意,无需使用grepsed执行任何后处理。此代码将为您创建两个文件:

awk 'NR%4==1 { getline one; printf "%s/1\n%s\n", $0, one > "reads_1.fa" } NR%4==3 { getline two; printf "%s/2\n%s\n", $0, two > "reads_2.fa" }' file.txt

<强>输入:

HWI-ST1018:1:1101:10007:34134#0
ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG
HWI-ST1018:1:1101:10007:34134#0
GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAGGAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG
HWI-ST1018:1:1101:10016:6488#0
ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAGAAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA
HWI-ST1018:1:1101:10016:6488#0
TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC

<强>结果:

reads_1.fa的内容:

HWI-ST1018:1:1101:10007:34134#0/1
ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG
HWI-ST1018:1:1101:10016:6488#0/1
ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAGAAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA

reads_2.fa的内容:

HWI-ST1018:1:1101:10007:34134#0/2
GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAGGAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG
HWI-ST1018:1:1101:10016:6488#0/2
TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC

答案 5 :(得分:1)

另一种解决方案:

awk 'BEGIN{RS=""}{if(NR<3){sub(/#0/,"#0/"NR);print $0,"\n"}else{NR=1;sub(/#0/,"#0/"NR);print $0,"\n"}}' file

结果:

awk 'BEGIN{RS=""}{if(NR<3){sub(/#0/,"#0/"NR); print $0,"\n"}else{NR=1;sub(/#0/,"#0/"NR);print $0, "\n"}}' file 
HWI-ST1018:1:1101:10007:34134#0/1 
ACTAGTAACCACATGTCCAGACTCCTCCTATGCTCCCACCCAGGGTCCCTTGAGCTGCTT 
CCCATTCCCCTAGGGCTGAGACCCAATATCCTCTATCCCTG 

HWI-ST1018:1:1101:10007:34134#0/2 
GTGCAGGCATGTTGGGGCGTGTCTCAGAGCCTGAACTTCCCTTCCAGTCAGTGCTGGAAG 
GAGGTGGGCAGGGGAATGATAGAAAGGAAGGAGTGGATTGG 

HWI-ST1018:1:1101:10016:6488#0/1 
ACAGCTATACACGAAGAATCTCAGCCCTTGTACTTTTGCATAGTCTCATACACGTATCAG 
AAGCCTCCACCTGGCTAACAGGAATTTGGGGCTTTGGGAGA 

HWI-ST1018:1:1101:10016:6488#0/2 
TTTGGGAGATTTTTTAATCAGGGCAAAACCTGTACTAGTAACCACATGTCCAGACTCCTC 
CTATGCTCCCACCCAGGGTCCCTTGAGCTGCTTCCCATTCC 
相关问题