linux - 在 AWK 中不知道确切位置的情况下替换缺失值
问题描述
我正在尝试处理从 ensemble 下载的GTF/GFF文件。文件的截断版本如下所示:
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
。
我真的很感激这方面的帮助!
解决方案
使用 awk 脚本;
脚本.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
在线演示。
推荐阅读
- json - 如何将 json 字符串数据类型列转换为配置单元中的映射数据类型列?
- mysql - 无法在 knex 节点 express 中将 multipleStatements 设置为 true
- android - 无法在屏幕底角绘制矩形
- c# - 如何从使用 dapper 返回的复杂对象中修剪所有字符串
- mysql - MariaDb 复制
- antlr4 - Antlr4 c++ 目标看起来像 java
- scilab - 在 xcos/scicos 中包含一个 Scilab 函数/脚本作为块
- matlab - 嵌套for循环不输出内部循环的值
- microsoft-cognitive - 教程语音意图识别不起作用?
- angular - 同时在 chrome 和 IE11 中支持 Angular Element 的问题