Разбор файла GenBank: получить тег locus против продукта
По сути, файл GenBank состоит из записей генов (объявляемых 'gene', за которыми следует соответствующая запись 'CDS' (только по одной на ген), подобно двум, которые я здесь показываю ниже. Я хотел бы получить locus_tag против продукта в символе с разделителями табуляции файл с двумя столбцами. 'gene' и 'CDS' всегда начинаются с пробелов.
Предыдущий вопрос предложил сценарий.
Проблема заключается в том, что, по-видимому, из-за того, что у "продукта" иногда есть символ "/" в имени, он конфликтует с этим сценарием, который, насколько я понимаю, использует "/" в качестве разделителя полей для хранения информации в массив?
Я хотел бы решить эту проблему, либо изменив этот скрипт, либо создав другой.
perl -nE'
BEGIN{ ($/, $") = ("CDS", "\t") }
say "@r[0,1]" if @r= m!/(?:locus_tag|product)="(.+?)"!g and @r>1
' file
gene complement(8972..9094)
/locus_tag="HAPS_0004"
/db_xref="GeneID:7278619"
CDS complement(8972..9094)
/locus_tag="HAPS_0004"
/codon_start=1
/transl_table=11
/product="hypothetical protein"
/protein_id="YP_002474657.1"
/db_xref="GI:219870282"
/db_xref="GeneID:7278619"
/translation="MYYKALAHFLPTLSTMQNILSKSPLSLDFRLLFLAFIDKR"
gene 68..637
/locus_tag="HPNK_00040"
CDS 68..637
/locus_tag="HPNK_00040"
/codon_start=1
/transl_table=11
/product="NinG recombination protein/bacteriophage lambda
NinG family protein"
/protein_id="CRESA:HPNK_00040"
/translation="MIKPKVKKRKCKCCGGEFKSADSFRKWCSAECGVKLAKIAQEKA
RQKAIEKRNREERAKIKATRERLKSRSEWLKDAQAIFNEYIRLRDKDEPCISCRRFHQ
GQYHAGHYRTVKAMPELRFNEDNVHKQCSACNNHLSGNITEYRINLVRKIGAERVEAL
ESYHPPVKWSVEDCKEIIKTYRAKIKELK"
2 ответа
Поскольку ваш пример файла GenBank был неполным, я вышел в Интернет, чтобы найти образец файла, который можно использовать в примере, и нашел этот файл.
Используя этот код и Bio::GenBankParser
Модуль, он был проанализирован, чтобы угадать, какие части структуры вы были после. В этом случае "функции", которые содержали как locus_tag
поле и product
поле.
use strict;
use warnings;
use feature 'say';
use Bio::GenBankParser;
my $file = shift;
my $parser = Bio::GenBankParser->new( file => $file );
while ( my $seq = $parser->next_seq ) {
my $feat = $seq->{'FEATURES'};
for my $f (@$feat) {
my $tag = $f->{'feature'}{'locus_tag'};
my $prod = $f->{'feature'}{'product'};
if (defined $tag and defined $prod) {
say join "\t", $tag, $prod;
}
}
}
Использование:
perl script.pl input.txt > output.txt
Выход:
MG_001 DNA polymerase III, beta subunit
MG_470 CobQ/CobB/MinD/ParA nucleotide binding domain-containing protein
Вывод из одной строки для того же ввода будет:
MG_001 DNA polymerase III, beta subunit
MG_470 CobQ/CobB/MinD/ParA nucleotide binding
domain-containing protein
Предполагая, конечно, что вы добавляете /s
Модификатор регулярного выражения для учета многострочных записей (на что указал Lee Duhem в комментариях):
m!/(?:locus_tag|product)="(.+?)"!sg
# ^---- this
Прочитав ваш дублированный вопрос http://www.biostars.org/p/94164/ (пожалуйста, не делайте двойной пост, как это), вот минимальный ответ Biopython:
import sys
from Bio import SeqIO
filename = sys.argv[1] # Takes first command line argument input filename
for record in SeqIO.parse(filename, "genbank"):
for feature in record.features:
if feature.type == "CDS":
locus_tag = feature.qualifiers.get("locus_tag", ["???"])[0]
product = feature.qualifiers.get("product", ["???"])[0]
print("%s\t%s" % (locus_tag, product))
С небольшими изменениями вы можете записать это в файл.