web-dev-qa-db-ja.com

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でそれを行うのは簡単だと私は知っています、そして実際、私はそれらの方法でそれを行うためのスクリプトを持っています。

13
cucurbit

awk/gawkソリューションは、次の3つの段階で構成できます。

  1. headerが見つかるたびに、次のアクションを実行する必要があります。

    • 前のシーケンスを出力存在する場合
    • タグを印刷します。
    • 初期化seqlen
  2. sequence行の場合、必要なのは合計を累積です。
  3. 最後に、ENDステージで、remnant seqlenを出力します。

コメントされたコード:

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

A 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

Awkを使用する簡単な方法は、次のとおりです。

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

あなたも興味があるかもしれません BioAwk 、それはFASTAファイルを処理するように調整されたawkの適応バージョンです

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

注:BioAwkBrian Kernighanのawk に基づいています。これは " AWKプログラミング言語」、Al Aho、Brian Kernighan、Peter Weinberger(Addison-Wesley、1988、ISBN 0-201-07981-X) 。このバージョンが [〜#〜] posix [〜#〜] と互換性があるかどうかはわかりません。

0
kvantour

Klashxxの答えに役立つかもしれないいくつかの微調整を共有したいと思いました。その出力は、シーケンスIDとその長さを1行に出力するという点で異なります。これは、もはや1ライナーではないため、欠点は、スクリプトファイルとして保存する必要があることです。

また、空白に基づいて、ヘッダー行からシーケンスIDを解析します(chrM in >chrM gi|251831106|ref|NC_012920.1|)。次に、変数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;
  }
}
0
Nick S