FASTA文件的序列长度

时间:2014-06-02 10:44:19

标签: bash awk fasta

我有以下FASTA文件:

>header1
CGCTCTCTCCATCTCTCTACCCTCTCCCTCTCTCTCGGATAGCTAGCTCTTCTTCCTCCT
TCCTCCGTTTGGATCAGACGAGAGGGTATGTAGTGGTGCACCACGAGTTGGTGAAGC
>header2
GGT
>header3
TTATGAT

我想要的输出:

>header1
117
>header2
3
>header3
7
# 3 sequences, total length 127.

这是我的代码:

awk '/^>/ {print; next; } { seqlen = length($0); print seqlen}' file.fa

我使用此代码获得的输出是:

>header1
60
57
>header2
3
>header3
7

我需要进行一些小修改才能处理多个序列行。

我还需要一种方法来获得总序列和总长度。欢迎任何建议......请在bash或awk中。我知道在Perl / BioPerl中很容易做到这一点,实际上,我有一个脚本可以用这些方式来做。

3 个答案:

答案 0 :(得分:17)

awk / gawk解决方案可以分为三个阶段:

  1. 每次发现header时,都应执行以下操作:

    • 打印上一个序列(如果存在)
    • 打印标签。
    • 初始化 seqlen
  2. 对于sequence行,我们只需要累计总计
  3. 最后在END阶段,我们打印残余序列
  4. 评论代码:

    awk '/^>/ { # header pattern detected
            if (seqlen){
             # print previous seqlen if exists 
             print seqlen
             }
    
             # pring the tag 
             print
    
             # initialize sequence
             seqlen = 0
    
             # skip further processing
             next
          }
    
    # accumulate sequence length
    {
    seqlen += length($0)
    }
    # remnant seqlen if exists
    END{if(seqlen){print seqlen}}' file.fa
    

    oneliner

    awk '/^>/ {if (seqlen){print seqlen}; print ;seqlen=0;next; } { seqlen += length($0)}END{print seqlen}' file.fa
    

    总计:

    awk '/^>/ { if (seqlen) {
                  print seqlen
                  }
                print
    
                seqtotal+=seqlen
                seqlen=0
                seq+=1
                next
                }
        {
        seqlen += length($0)
        }     
        END{print seqlen
            print seq" sequences, total length " seqtotal+seqlen
        }' file.fa
    

答案 1 :(得分:0)

我想与klashxx的回答分享一些可能有用的调整。它的输出不同之处在于它在一行上打印序列id及其长度,它不再是单行,所以缺点是你必须将它保存为脚本文件。

它还会根据空格(chrM中的>chrM gi|251831106|ref|NC_012920.1|)从标题行中解析出序列ID。然后,您可以通过设置变量target来选择基于ID的特定序列,如下所示:$ awk -f seqlen.awk -v target=chrM seq.fa

BEGIN {
  OFS = "\t"; # tab-delimited output
}
# Use substr instead of regex to match a starting ">"
substr($0, 1, 1) == ">" {
  if (seqlen) {
    # Only print info for this sequence if no target was given
    # or its id matches the target.
    if (! target || id == target) {
      print id, seqlen;
    }
  }
  # Get sequence id:
  # 1. Split header on whitespace (fields[1] is now ">id")
  split($0, fields);
  # 2. Get portion of first field after the starting ">"
  id = substr(fields[1], 2);
  seqlen = 0;
  next;
}
{
  seqlen = seqlen + length($0);
}
END {
  if (! target || id == target) {
    print id, seqlen;
  }
}

答案 2 :(得分:0)

使用任何awk的快速方法是:

awk '/^>/{if (l!="") print l; print; l=0; next}{l+=length($0)}END{print l}' file.fasta

您可能还对BioAwk感兴趣,它是awk的改编版本,已调整为处理FASTA文件

bioawk -c fastx '{print ">" $name ORS length($seq)}' file.fasta

注意:BioAwk基于Brian Kernighan's awk中记录的"The AWK Programming Language", by Al Aho, Brian Kernighan, and Peter Weinberger (Addison-Wesley, 1988, ISBN 0-201-07981-X) 。我不确定该版本是否与POSIX兼容。