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

如何用Awk实现file_1第2列与file_2列范围匹配并合并行?

解决制表符文件区间匹配合并问题

文件内容

file_1(制表符分隔)

NC_025       4569   .   KX838946.2      
NC_025       16546  .   KJ641660.1      
NC_025       11996  .   KX932454.2

file_2(制表符分隔)

NC_025.1     RefSeq  gene    5690    7513    .       +       .       ID=gene-NZ82_gp4;Dbxref=GeneID:20964334;Name=NZ82_gp4;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp4
NC_025.1     RefSeq  gene    4612    10046   .       +       .       ID=gene-NZ82_gp5;Dbxref=GeneID:20964335;Name=NZ82_gp5;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp5
NC_025.1     RefSeq  gene    10337   16933   .       +       .       ID=gene-NZ82_gp6;Dbxref=GeneID:20964336;Name=NZ82_gp6;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp6
NC_025.1     RefSeq  gene    9000    12000    .      +       .       ID=gene-AL82_gp5;Dbxref=GeneID:109647334;Name=AL82_gp5;gbkey=Gene;gene_biotype=protein_coding;locus_tag=AL82_gp5

需求

将file_1每行的第2列数值,与file_2每行的第4、5列数值区间(≥第4列且≤第5列)对比,满足条件则将两行合并输出。预期输出:

NC_025       16546   .   KJ641660.1     NC_025.1     RefSeq  gene    10337   16933   .       +       .       ID=gene-NZ82_gp6;Dbxref=GeneID:20964336;Name=NZ82_gp6;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp6    
NC_025       11996   .   KX932454.2     NC_025.1     RefSeq  gene    10337   16933   .       +       .       ID=gene-NZ82_gp6;Dbxref=GeneID:20964336;Name=NZ82_gp6;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp6
NC_025       11996   .   KX932454.2     NC_025.1     RefSeq  gene    9000    12000    .       +       .       ID=gene-AL82_gp5;Dbxref=GeneID:109647334;Name=AL82_gp5;gbkey=Gene;gene_biotype=protein_coding;locus_tag=AL82_gp5

原代码问题

你尝试的awk代码无输出,核心问题是逻辑错误:用FNR关联两个文件的行号,仅让file_2的第N行和file_1的第N行对比,但需求是file_1的每一行都要和file_2的所有行做区间匹配,而非按行号对应。

awk '{
  if (NR==FNR) {
  l[NR]=$0
  a[NR]=$2
 }
  else if (a[FNR]>=$4 && a[FNR]<=$5) {
  print l[FNR],$0
 }
}' file_1 file_2 > File_3

正确解决方案

改用以下awk代码,实现file_1所有行与file_2所有行的全量匹配:

awk 'BEGIN {FS=OFS="\t"}
NR==FNR {
    # 存储file_1的每一行内容和第2列数值
    lines[++n] = $0
    vals[n] = $2
    next
}
{
    # 遍历file_1的所有行,逐一匹配区间
    for (i=1; i<=n; i++) {
        if (vals[i] >= $4 && vals[i] <= $5) {
            print lines[i], $0
        }
    }
}' file_1 file_2 > File_3

代码说明

  1. BEGIN {FS=OFS="\t"}:明确指定输入输出分隔符为制表符,保证格式一致
  2. 读取file_1时,用数组lines存储完整行内容,vals存储第2列数值,n记录file_1的行数
  3. 读取file_2时,遍历file_1的所有行,检查当前file_2行的区间是否包含file_1行的数值,满足则打印合并行

运行该代码后,输出结果与预期完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 01:00:10