使用 awk 或 sed 提取具有特定模式的部分行并存储在新字段中

使用 awk 或 sed 提取具有特定模式的部分行并存储在新字段中

我的问题类似于这个,但我想要提取的部分位于该行内,我还想将其存储在原始文件中新创建的列中,而不是输出中。

我的制表符分隔文件中的一行如下所示:

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上面的脚本在哪里。

相关内容