#linux #unix
#linux #unix
Вопрос:
Я пытаюсь обработать файл GTF / GFF, который я загружаю из ensemble. Усеченная версия файла выглядит следующим образом:
1 ensembl gene 5273 10061 . - . gene_id ENSGALG00000054818; gene_version 1; gene_source ensembl; gene_biotype protein_coding;
1 ensembl transcript 5273 10061 . - . gene_id ENSGALG00000054818; gene_version 1; transcript_id ENSGALT00000098984; transcript_version 1; gene_source ensembl; gene_biotype protein_coding; transcript_source ensembl; transcript_biotype protein_coding;
1 ensembl gene 58427 58617 . . gene_id ENSGALG00000047594; gene_version 1; gene_name RF00004; gene_source ensembl; gene_biotype snRNA;
1 ensembl transcript 58427 58617 . . gene_id ENSGALG00000047594; gene_version 1; transcript_id ENSGALT00000094382; transcript_version 1; gene_name RF00004; gene_source ensembl; gene_biotype snRNA; transcript_name RF00004-201; transcript_source ensembl; transcript_biotype snRNA;
1 ensembl exon 58427 58617 . . gene_id ENSGALG00000047594; gene_version 1; transcript_id ENSGALT00000094382; transcript_version 1; exon_number 1; gene_name RF00004; gene_source ensembl; gene_biotype snRNA; transcript_name RF00004-201; transcript_source ensembl; transcript_biotype snRNA; exon_id ENSGALE00000460125; exon_version 1;
1 ensembl gene 63264 63454 . . gene_id ENSGALG00000049206; gene_version 1; gene_name RF00004; gene_source ensembl; gene_biotype snRNA;
1 ensembl transcript 63264 63454 . . gene_id ENSGALG00000049206; gene_version 1; transcript_id ENSGALT00000092780; transcript_version 1; gene_name RF00004; gene_source ensembl; gene_biotype snRNA; transcript_name RF00004-201; transcript_source ensembl; transcript_biotype snRNA;
1 ensembl exon 63264 63454 . . gene_id ENSGALG00000049206; gene_version 1; transcript_id ENSGALT00000092780; transcript_version 1; exon_number 1; gene_name RF00004; gene_source ensembl; gene_biotype snRNA; transcript_name RF00004-201; transcript_source ensembl; transcript_biotype snRNA; exon_id ENSGALE00000501941; exon_version 1;
(Девять столбцов, разделенных табуляцией.)
В некоторых строках отсутствуют атрибуты, такие как gene_name
, transcript_id
или transcript_name
.
- Если
gene_name
отсутствует, я хотел заменить его наgene_id
, - и если
transcript_name
отсутствует, я хотел заменить его наtranscript_id
(в случае отсутствияtranscript_id
оно заменяется наgene_id
).
Однако информация для transcript_id
или, лучше сказать, положение этой информации неизвестно. Как бы я искал атрибут и, в случае его отсутствия, заменил его значением transcript_id
с неизвестной информацией о местоположении
Я добился замены отсутствующего значения для gene_name
на значение для gene_id
следующим образом:
awk '{if (!/gene_name/) print $0, "gene_name " $10; else print $0}' input.gtf > output.gtf
Это сработало довольно хорошо, но только потому, что в данном конкретном случае я знал позицию значения, которое я использовал в качестве замены. Я не мог понять, как я добьюсь этого, когда позиция совпадения неизвестна.
Я использовал следующий код для получения неизвестной информации о местоположении, но не смог интегрировать проверку на несоответствие, как в первом примере выше:
awk '{for (i=1; i<=NF; i) { if ($i ~ "transcript_name") print$0,"transcript_name ", $(i 1) } }' input.gtf > output.gtf
Условие состоит в том, что только если transcript_name
оно еще не присутствует в строке, его следует заменить значением для transcript_id
.
Я действительно был бы признателен за помощь в этом!
Комментарии:
1. Спасибо за ваше предложение. Я посмотрю на perl! Пример, на который вы ссылались, делает именно то, что я хотел. Однако я не могу запустить его, похоже, есть «синтаксическая ошибка возле неожиданного токена`(‘ «, которую я не смог найти. У вас есть идея, где может возникнуть эта ошибка?
2. посмотрите мой ответ и дайте мне знать, если вы все еще получаете ошибки.
Ответ №1:
Использование скрипта awk;
script.awk:
#!/usr/bin/awk -f
BEGIN {
FS=OFS="t"
}
{
gsub(/; *$/, "", $9) # trim trailing `;'
split($9, pairs, / *; */) # split attributes into pairs
for (i in pairs) {
split(pairs[i], kv, / */) # split pair into key and value
attr[kv[1]] = kv[2] # add it to `attr'
}
# fill missing fields
if (!("gene_name" in attr))
attr["gene_name"] = attr["gene_id"]
if (!("transcript_id" in attr))
attr["transcript_id"] = attr["gene_id"]
if (!("transcript_name" in attr))
attr["transcript_name"] = attr["transcript_id"];
# recreate the attributes field
attr_all = sep = ""
for (k in attr) {
attr_all = attr_all sep k " " attr[k]
sep = "; "
}
# update the record with new attributes
$9 = attr_all
}
1 # print record
Пример использования:
awk -f script.awk inputfile
Комментарии:
1. Извините, я не знал, как использовать скрипт awk. Спасибо за разъяснение, это отлично сработало!.
2. Как бы вы изменили код, чтобы пропустить заголовок файла (5 строк), а затем начать генерировать массив для атрибутов? Я попытался изменить параметры в начале « awk -f BEGIN {FNR>5;FS= OFS=» t»} …..« но, к сожалению, это работало не так, как ожидалось. Если файл содержит заголовок, то ваш код выдает имена атрибутов, но без какого-либо значения.
3. @PhiH вставьте
NR>5
перед{
в 5-ю строку скрипта.4. Работает отлично! Я думал, что должен был указать это раньше, спасибо за быстрое исправление!