我的问题类似于这个,但我想要提取的部分位于该行内,我还想将其存储在原始文件中新创建的列中,而不是输出中。
我的制表符分隔文件中的一行如下所示:
chr1 25228613 25229157 CDS HAVANA . - 2 ID=CDS:ENST00000338888.3;Parent=ENST00000338888.3;gene_id=ENSG00000020633.18_3;transcript_id=ENST00000338888.3_2;gene_type=protein_coding;gene_name=RUNX3;transcript_type=protein_coding;transcript_name=RUNX3-202;exon_number=7;exon_id=ENSE00001384103.2;level=2;protein_id=ENSP00000343477.3;transcript_support_level=1;tag=basic,appris_alternative_2,CCDS;ccdsid=CCDS30633.1;havana_gene=OTTHUMG00000003316.1_3;havana_transcript=OTTHUMT00000009285.1_2;remap_original_location=chr1:-:24902122-24902666;remap_status=full_contig
我想提取$9中“gene_name”后面的内容,这一行是RUNX3。
预期输出:
chr1 25228613 25229157 CDS HAVANA . - 2 ID=CDS:ENST00000338888.3;Parent=ENST00000338888.3;gene_id=ENSG00000020633.18_3;transcript_id=ENST00000338888.3_2;gene_type=protein_coding;gene_name=RUNX3;transcript_type=protein_coding;transcript_name=RUNX3-202;exon_number=7;exon_id=ENSE00001384103.2;level=2;protein_id=ENSP00000343477.3;transcript_support_level=1;tag=basic,appris_alternative_2,CCDS;ccdsid=CCDS30633.1;havana_gene=OTTHUMG00000003316.1_3;havana_transcript=OTTHUMT00000009285.1_2;remap_original_location=chr1:-:24902122-24902666;remap_status=full_contig RUNX3
如何使用 awk 或 sed 来做到这一点?
答案1
既然您知道分隔符,那么只需在这些分隔符上进行拆分和重新组合即可
sed -Ei 's/(.*gene_name=)([^;]*)(;.*)/\1\2\3\t\2/g' gene
它分为
(.*gene_name=)
直到gene_name标签的所有字符串都进入变量1
([^;]*)
; 之前的所有连续字符进入变量2
(;.*)
字符串的其余部分进入变量 3
\1\2\3\t\2
使用制表符和附加的基因重新组合字符串
编辑
或如@Weijun 所说
\0\t\2
另一个编辑
代码高尔夫
sed -Ei 's/.*gene_name=([^;]*).*/\0\t\1/g' gene
答案2
和gawk
:
gawk 'match($9,/^.*gene_name=([^;]*);.*/,arr) {print $0"\t"arr[1]}'
这会将gene_name 附加到包含“gene_name=”字符串的每行的末尾。您可以根据您的需要对其进行微调。
答案3
以下awk
也可能对您有所帮助。
awk '{val=$0;sub(/.*gene_name=/,"",val);sub(/\;.*/,"",val);print $0,val}' Input_file
答案4
这是awk
从文件的属性字段(第 9 个制表符分隔字段)中解析出特定命名字段的通用解决方案通用特征格式 (GFF):
BEGIN { OFS = FS = "\t" }
function get_attrib_by_name(key, n,attrib,kv) {
# Split the attribute field on semi-colons.
n = split($9, attrib, ";")
# Loop over the attributes and split each on "=".
# When we've found the one we're looking for (by key name in "key"),
# return the corresponding value.
for (i = 1; i <= n; ++i) {
split(attrib[i], kv, "=")
if (kv[1] == key) {
return kv[2]
}
}
}
# Using the above function.
{
name = get_attrib_by_name("gene_name")
print $0, name
}
这会像这样使用
$ awk -f script.awk file.gff
script.awk
上面的脚本在哪里。