根据第二个文件中的特定值选择一个文件中的行

根据第二个文件中的特定值选择一个文件中的行

我有两个文件:

一种是“total.txt”。它有两列:第一列是范围从 1 到 20 的自然数(指标),第二列包含随机数。

1 321
1 423
1 2342
1 7542
2 789
2 809
2 5332
2 6762
2 8976
3 42
3 545
... ...
20 432
20 758

另一个是“index.txt”。它有四列:(1.指标,2:低值,3:高值,4:区域名称)

1 400 5000 R1
2 600 800 R2
2 4000 8000 R3
11 300 4000 R4

我想输出“total.txt”文件的行,其中第一列与“index.txt”文件的第一列匹配。同时,输出结果的第二列必须大于(>)“index.txt”的第二列,小于(<)“index.txt”的第三列。并应附上地区名称。

预期结果如下:

1 423 R1
1 2342 R1
2 809 R2
2 5332 R3
2 6762 R3
11 ... R4
11 ... R4

我已经尝试过这个:

awk 'FNR == NR { low[$1]=$2; high[$1]=$3; reg[$1]=$4; next} 
     $2 >= low[$1] && $2 <= high[$1] {print $0,reg[$1]}' index.txt total.txt > result.txt

结果如下(缺少区域R2)

1 423 R1
1 2342 R1
2 5332 R3
2 6762 R3
11 ... R4
11 ... R4

您能帮我解释一下并告诉我如何处理吗?谢谢你!

实际上,如果能够按照不同区域输出结果就更好了,这意味着在本例中,最好生成4个涉及不同区域的文本文件(R1.txt、R2.txt、R3.txt和R4.txt)。谢谢!

答案1

两个输入文件(第一列)中的指示符不是唯一的,因此很难将它们用作键。但如果区域 ID 是唯一的,我们可以使用这些:

 $ awk 'FNR == NR { reg=$4; low[reg]=$2; high[reg]=$3; ind[reg]=$1; next} 
  { for (reg in ind) { 
      if ($1 == ind[reg] && $2 >= low[reg] && $2 <= high[reg]) {
         print $0,reg
      } } }' index.txt total.txt
1 423 R1
1 2342 R1
2 789 R2
2 5332 R3
2 6762 R3

这基本上就是您的代码,添加了 for 循环以将区域映射到其指标,并检查第二个文件中的哪些行匹配。

(至于2 789 R2vs 2 809 R2,我不确定如果限制是 600 和 800,为什么应该打印 809 。)

将 print 命令更改为print $0,reg > reg ".txt"将输出输出到按区域命名的文件中。

相关内容