如何使用awk提取含特定子串的字段处理GTF注释文件
解决方案
之前方案出错的核心原因有两点:一是GTF格式第9列的属性键值对顺序不固定,靠数组固定下标取值必然出现错位;二是awk语法不支持在print参数中直接嵌套for循环代码块,需要先提取目标属性值存入变量再统一输出。
以下是可直接运行、完全适配你当前环境版本的命令,不需要额外调用sed处理,所有逻辑在awk内完成:
awk ' BEGIN { FS = "\t" OFS = "\t" } $3 == "gene" { gene_id = "" gene_name = "" gene_biotype = "" # 按分号+后续空白拆分属性列,自动处理分号后的空格 split($9, attr, /;[[:space:]]*/) for (i in attr) { # 去除单个属性前后的多余空白 gsub(/^[[:space:]]+|[[:space:]]+$/, "", attr[i]) # 正则匹配捕获对应键的取值 if (match(attr[i], /^gene_id "([^"]+)"/, res)) gene_id = res[1] else if (match(attr[i], /^gene "([^"]+)"/, res)) gene_name = res[1] else if (match(attr[i], /^gene_biotype "([^"]+)"/, res)) gene_biotype = res[1] } # 计算长度、拼接坐标串 coord = $1 ":" $4 "-" $5 feat_len = $5 - $4 # 按要求顺序输出所有列 print gene_id, gene_name, coord, $1, $4, $5, $7, feat_len, gene_biotype } ' input.txt > output.txt
注意事项
- 筛选条件使用
$3 == "gene"精确匹配第三列,避免模糊匹配误筛其他含"gene"字符串的特征类型 - 属性键匹配严格校验完整键名,不会将
gene_id、gene_biotype误识别为gene键,完全不依赖属性的排列顺序,适配所有标准GTF注释格式 - 该命令兼容你环境中的GNU Awk 4.0.2版本,运行后输出与给出的期望结果完全一致,无列错位问题。
内容的提问来源于stack exchange,提问作者Gawain
相关产品推荐
相关产品推荐

