Проблема с циклической печатью на perl при анализе файлов

#regex #perl #sequence #text-parsing

Вопрос:

У меня есть этот результат от фобиуса, который выглядит следующим образом

 ID   sp|Q92673|1-2157
FT   SIGNAL        1     28       
FT   DOMAIN        1     11       N-REGION.
FT   DOMAIN       12     22       H-REGION.
FT   DOMAIN       23     28       C-REGION.
FT   DOMAIN       29   2135       NON CYTOPLASMIC.
FT   TRANSMEM   2136   2156       
FT   DOMAIN     2157   2157       CYTOPLASMIC.
//
---------------------------------------------------------------------
ID   sp|Q5SSG8|25-479
FT   DOMAIN        1    455       NON CYTOPLASMIC.
//
---------------------------------------------------------------------
ID   sp|Q92854|22-734
FT   DOMAIN        1    713       NON CYTOPLASMIC.
//
---------------------------------------------------------------------
ID   sp|Q9Y5E9|27-686
FT   DOMAIN        1    660       NON CYTOPLASMIC.
// 
---------------------------------------------------------------------
ID   sp|Q9Y6N8|55-613
FT   DOMAIN        1    559       NON CYTOPLASMIC.
//
 

Я хочу напечатать соответствующий идентификатор Uniprot перед каждой строкой для каждого результата отдельно \ .

Вот фрагмент кода perl, который я создал

 open (MYFILE, "result_phobius.txt" )||warn "Couldn't open file because $!"; #give input file name
open (FILE, ">output.txt"); #output file name
while (<MYFILE>)
{
    if ($_=~/^ID   (S ?)s/) #search accession number started by > and terminate at white space
    {
        $id=$1;
        chomp ($id);
        print FILE "$idt"; #will print accession number in a column
    }
        if ($_=~/^FT   /)
        
    {
        print FILE "$_";
        
    }
}
 

Это печатает идентификатор только в первой строке, т. Е. Он отлично работает с результатами, имеющими один домен, но терпит неудачу, если существует более одного домена.

например

 FT   SIGNAL        1     28       
FT   DOMAIN        1     11       N-REGION.
FT   DOMAIN       12     22       H-REGION.
FT   DOMAIN       23     28       C-REGION.
FT   DOMAIN       29   2135       NON CYTOPLASMIC.
FT   TRANSMEM   2136   2156       
FT   DOMAIN     2157   2157       CYTOPLASMIC.
sp|Q5SSG8|25-479    FT   DOMAIN        1    455       NON CYTOPLASMIC.
sp|Q92854|22-734    FT   DOMAIN        1    713       NON CYTOPLASMIC.
sp|Q9Y5E9|27-686    FT   DOMAIN        1    660       NON CYTOPLASMIC.
sp|Q9Y6N8|55-613    FT   DOMAIN        1    559       NON CYTOPLASMIC.
sp|Q02763|23-748    FT   DOMAIN        1    726       NON CYTOPLASMIC.
sp|Q14517|22-4181   FT   DOMAIN        1   4160       NON CYTOPLASMIC.
sp|O75051|35-1237   FT   DOMAIN        1   1203       NON CYTOPLASMIC.
tr|D3DPA4|1-145 FT   DOMAIN        1    119       CYTOPLASMIC.
FT   TRANSMEM    120    144       
FT   DOMAIN      145    145       NON CYTOPLASMIC.
 

как я могу заставить его работать для нескольких записей?

ожидаемый результат

 sp|Q92673|1-2157    FT   SIGNAL        1     28       
sp|Q92673|1-2157    FT   DOMAIN        1     11       N-REGION.
sp|Q92673|1-2157    FT   DOMAIN       12     22       H-REGION.
sp|Q92673|1-2157    FT   DOMAIN       23     28       C-REGION.
sp|Q92673|1-2157    FT   DOMAIN       29   2135       NON CYTOPLASMIC.
sp|Q92673|1-2157    FT   TRANSMEM   2136   2156       
sp|Q92673|1-2157    FT   DOMAIN     2157   2157       CYTOPLASMIC.
sp|Q5SSG8|25-479    FT   DOMAIN        1    455       NON CYTOPLASMIC.
sp|Q92854|22-734    FT   DOMAIN        1    713       NON CYTOPLASMIC.
sp|Q9Y5E9|27-686    FT   DOMAIN        1    660       NON CYTOPLASMIC.
sp|Q9Y6N8|55-613    FT   DOMAIN        1    559       NON CYTOPLASMIC.
sp|Q02763|23-748    FT   DOMAIN        1    726       NON CYTOPLASMIC.
sp|Q14517|22-4181   FT   DOMAIN        1   4160       NON CYTOPLASMIC.
sp|O75051|35-1237   FT   DOMAIN        1   1203       NON CYTOPLASMIC.
tr|D3DPA4|1-145     FT   DOMAIN        1    119       CYTOPLASMIC.
tr|D3DPA4|1-145     FT   TRANSMEM    120    144       
tr|D3DPA4|1-145     FT   DOMAIN      145    145       NON CYTOPLASMIC.
 

Заранее спасибо за помощь

Комментарии:

1. Это похоже на программу, которая была бы проще в обслуживании и более гибкой, если бы вы написали ее как фильтр Unix. Удалите все открывающиеся файлы. Читайте STDIN , пишите STDOUT и называйте это как my_program.pl < result_phobius.txt > output.txt .

Ответ №1:

Просто переместите print FILE "$idt" в другой if блок, т. Е. заполняйте $id только тогда, когда он указан, распечатайте его для каждого домена.

Вы можете добавить проверку того, что идентификатор $не пуст перед его печатью, но этого не должно произойти, если я правильно понимаю формат.

    if (/^ID   (S ?)s/)
   {
        $id = $1;
   }
   if (/^FT   /)
   {
        print FILE "$idt$_";
   }
 

Комментарии:

1. ..Я пробую это ` «если ($_=~/^FT /) файл печати» $idt»; {файл печати»$_`;}}»», но он печатает имена uniprot дважды, один раз со строкой идентификатора и второй раз со всеми строками FT

2. @Kay: Я сказал «в блок», а не «до». Обновил ответ.

3. … Спасибо { if ($_=~/^ID (S ?)s/) #search accession number started by > and terminate at white space { $id=$1; chomp ($id); #print FILE "$idt"; #will print accession number in a colomn } if ($_=~/^FT /) { print FILE "$idt"; print FILE "$_"; } } , это тоже помогает