Длина последовательности файла 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(); print seqlen}' file.fa

вывод, который я получаю с этим кодом:

>header1
60
57
>header2
3
>header3
7

мне нужна небольшая модификация, чтобы иметь дело с несколькими строками последовательности.

мне также нужен способ иметь общие последовательности и общую длину. Любое предложение будет приветствоваться... в bash или awk, пожалуйста. Я знаю, что это легко сделать в Perl / BioPerl, и на самом деле я есть скрипт, чтобы сделать это таким образом.

2 ответов


An awk / gawk решение может быть составлено в три этапа:

  1. каждый раз header не найдено, что эти действия должны быть выполнены:

    • печать предыдущего seqlen при наличии.
    • тег печати.
    • инициализации seqlen.
  2. на sequence линии нам просто нужно накапливать составляет.
  3. наконец на END этап мы печатаем остаток 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()
}
# remnant seqlen if exists
END{if(seqlen){print seqlen}}' file.fa

A oneliner:

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

на суммы:

awk '/^>/ { if (seqlen) {
              print seqlen
              }
            print

            seqtotal+=seqlen
            seqlen=0
            seq+=1
            next
            }
    {
    seqlen += length()
    }     
    END{print seqlen
        print seq" sequences, total length " seqtotal+seqlen
    }' file.fa

Я хотел поделиться некоторыми настройками ответа klashxx, которые могут быть полезны. Его выход отличается тем, что он печатает идентификатор последовательности и ее длину на одной строке, это больше не однострочный, поэтому вам придется сохранить его как файл сценария.

Он также анализирует идентификатор последовательности из строки заголовка на основе пробелов (chrM на >chrM gi|251831106|ref|NC_012920.1|). Затем вы можете выбрать определенную последовательность на основе идентификатора, установив переменную target вот так: $ 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(, 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(, fields);
  # 2. Get portion of first field after the starting ">"
  id = substr(fields[1], 2);
  seqlen = 0;
  next;
}
{
  seqlen = seqlen + length();
}
END {
  if (! target || id == target) {
    print id, seqlen;
  }
}