You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:用awk分割Geneid字段并拼接至Chr列的正确实现方法

解决制表符分隔文件的字段修改问题

需求说明

现有一个制表符分隔的输入文件,结构如下:

Geneid  Chr Start   End Strand  Length  WI_D_9_18_21_A_contigs_sorted.bam
1_1 c_1246  1   1395    +   1395    1028
1_2 c_1246  1407    2168    +   762 821
1_3 c_1246  2198    2971    +   774 874
1_4 c_1246  2986    3969    +   984 938
1_5 c_1246  4163    5047    +   885 874
1_6 c_1246  5085    5333    +   249 362
1_7 c_1246  5549    5878    +   330 493
1_8 c_1246  6057    6713    +   657 696

需要生成一个新的制表符分隔文件,包含以下列:

  1. Geneid(原第1列)
  2. 修改后的Chr:将Geneid字段中下划线后的数字部分追加到原Chr字段末尾,格式为Chr_数字
  3. Length(原第6列)
  4. 原第7列

期望输出如下:

Geneid  Chr Length  WI_D_9_18_21_A_contigs_sorted.bam
1_1 c_1246_1    1395    1028
1_2 c_1246_2    762 821
1_3 c_1246_3    774 874
1_4 c_1246_4    984 938
1_5 c_1246_5    885 874
1_6 c_1246_6    249 362
1_7 c_1246_7    330 493
1_8 c_1246_8    657 696
1_9 c_1246_9    663 725

错误尝试

尝试了以下awk命令,但无法正确追加数字,输出的Chr字段末尾只有下划线:

awk -F '	' '{OFS = FS} FNR<=1{next} NR>2 {split($1,a,_); $2 = $2 "_" a[$2];} 1 {print $1,$2,$6,$7}' WI_D_9_18_21_A_bin.6_fC_gene_coverage.tsv > test.txt

awk -F '	' '{OFS = FS} FNR<=1{next} {n[$1,$2]=split($1,a,"_");} NR>1 {print $1,$2 "_" n[$2],$6,$7}' WI_D_9_18_21_A_bin.6_fC_gene_coverage.tsv > test.txt

awk -F '	' '{OFS = FS} FNR<=1{next} {split($1,a,"_");next} FNR>1 {print $1,$2 "_" a[$2],$6,$7}' WI_D_9_18_21_A_bin.6_fC_gene_coverage.tsv > test.txt

错误输出示例:

Geneid  Chr Length  WI_D_9_18_21_A_contigs_sorted.bam
1_1 c_1246_ 1395    1028
1_2 c_1246_ 762 821
1_3 c_1246_ 774 874
1_4 c_1246_ 984 938
1_5 c_1246_ 885 874
1_6 c_1246_ 249 362
1_7 c_1246_ 330 493
1_8 c_1246_ 657 696
1_9 c_1246_ 663 725

正确解法

问题出在split后的数组索引使用错误:当用split($1,a,"_")分割Geneid(如1_1)时,数组a的a[1]是1,a[2]是下划线后的数字部分,你之前错误地用了a[$2],这会取数组中不存在的索引,导致输出空值。

正确的awk命令如下:

awk -F '\t' -v OFS='\t' '
    NR==1 {print $1, $2, $6, $7; next}
    {
        split($1, a, "_")
        new_chr = $2 "_" a[2]
        print $1, new_chr, $6, $7
    }
' WI_D_9_18_21_A_bin.6_fC_gene_coverage.tsv > test.txt

命令解释:

  1. -F '\t' -v OFS='\t':指定输入和输出的分隔符都是制表符,确保列对齐。
  2. NR==1 {print $1, $2, $6, $7; next}:处理第一行表头,直接输出需要的列,然后跳过后续处理。
  3. split($1, a, "_"):将Geneid字段按下划线分割到数组a中。
  4. new_chr = $2 "_" a[2]:拼接原Chr字段和Geneid分割后的第二部分数字。
  5. print $1, new_chr, $6, $7:输出最终需要的四列。

也可以用更简洁的写法,利用awk的字符串匹配特性,不用split:

awk -F '\t' -v OFS='\t' '
    NR==1 {print $1, $2, $6, $7; next}
    {print $1, $2 "_" substr($1, index($1,"_")+1), $6, $7}
' WI_D_9_18_21_A_bin.6_fC_gene_coverage.tsv > test.txt

这个写法通过index($1,"_")找到下划线的位置,用substr截取后面的数字部分,直接拼接。

内容的提问来源于stack exchange,提问作者Linton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:22:33