私は次の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でそれを行うのは簡単だと私は知っています、そして実際、私はそれらの方法でそれを行うためのスクリプトを持っています。
awk
/gawk
ソリューションは、次の3つの段階で構成できます。
header
が見つかるたびに、次のアクションを実行する必要があります。
sequence
行の場合、必要なのは合計を累積です。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
注:BioAwk は Brian Kernighanのawk に基づいています。これは " AWKプログラミング言語」、Al Aho、Brian Kernighan、Peter Weinberger(Addison-Wesley、1988、ISBN 0-201-07981-X) 。このバージョンが [〜#〜] posix [〜#〜] と互換性があるかどうかはわかりません。
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;
}
}