sed将多行bloc转换为单行(例如:fasta到phylip格式)

时间:2017-10-24 10:40:43

标签: sed fasta

简短

如何使用sed将fasta转换为类似“phylip”的格式(文件顶部没有序列和残留计数)?

fasta格式是这样的:

>sequence1
AATCG
GG-AT
>sequence2
AGTCG
GGGAT

序列的行数可能会有所不同。

我想将其转换为:

sequence1 AATCG GG-AT
sequence2 AGTCG GGGAT

我的问题看似简单,但我对sed中的高级命令,多行命令和使用保持缓冲区的命令缺乏真正的了解。

这是我的实施想法: 用序列填充模式空间,只在遇到新的序列标签时打印它。要做到这一点,我会:

  1. 搜索与^>匹配的行。如果找到:
    • 打印上一个模式空间
    • 将行添加到模式空间
  2. 如果找不到^>
    • 将行添加到模式空间
  3. 我读了这篇伟大的manual, 但我仍然不确定一些事情,主要是大写字母和小写字母之间的区别:

    • 当您使用P代替p时: 它是否打印模式空间的第一个行(按文件顺序)? 我对使用“直到下一个换行符”感到困惑。
    • 我必须使用循环来读取行,直到下一个序列名称,或多行命令是否足够?
    • 我必须在此示例中使用保留空间吗?

    我知道python,perl和awk ,我认为他们将是更加“人性化”的工具来实现这一目标,但我想学习一些先进的sed。

    我现在没有尝试过任何工作,但这里有一些部分:

    此脚本使用行号,而不是尝试进行模式匹配。 它是我想要做的,现在我需要使用匹配地址自动化它:

    #!/bin/sed -nf
    1h
    2,3H
    4{x; s/\n/ /g; p}
    5H
    6{H;x; s/\n/ /g; p}
    

    sed -nf fa2phy.sed my.fasta返回预期的输出。

3 个答案:

答案 0 :(得分:1)

使用sed

sed '/>/N;:A;/\n>/!{s/\n/ /;N;bA};h;s/\(.*\)\n.*/\1/p;x;s/.*\n//;bA' infile

答案 1 :(得分:0)

以下简单的awk可以帮助你。

解决方案1:

awk '/^>/{sub(/>/,"");if(val){print val, val2};val=$0;val2="";next} {val2=val2?val2 FS $0:$0} END{print val, val2}'  Input_file

解决方案第二:

awk -v RS=">" -v FS="\n" '{for(i=1;i<=NF;i++){printf("%s%s",$i,i==NF?"\n":" ")}}'   Input_file

解决方案第3名:

awk -v RS=">" '{gsub(/\n/," ");} NF'   Input_file

答案 2 :(得分:0)

好吧,我相信我设法回答了我自己的问题。

以下是我制作的脚本:fa2phy.sed

#!/bin/sed -nf

:readseq
${H;b out}              # if last line, append to hold, and goto 'out'
1{h;n;b readseq}        # if first, overwrite hold, and start again at 'readseq'
/^>/!{H; n; b readseq}  # if not a sequence label, append to hold, read next line, start again at 'readseq'. Else, it continues to 'out'

:out
x;         # exchange hold content with pattern content
s/^>//;    # substitute the starting '>'
s/\n/  /g; # substitute each newline with 2 spaces
p;         # print pattern buffer

虽然它有效但如果有人有更短或更清晰的解决方案,请启发我! :)