首页 > 解决方案 > 如果值介于文件 2 中的间隔之间,则加入两个 csv 文件

问题描述

我有两个需要加入的 csv 文件,F1 有数百万行,F2(文件 1)有数千行。如果文件 F1 (F1.pos) 中的位置在 F2.start 和 F2.end 之间,我需要加入这些文件。有什么办法,如何在bash中做到这一点?因为我在 Python pandas 中有一个到 sqllite3 的代码,我正在寻找更快的东西。

表 F1 如下所示:

| name  | pos   |
|------ |------ |
| a     | 1020  |
| b     | 1200  |
| c     | 1800  |

表 F2 如下所示:

| interval_name     | start     | end   |
|---------------    |-------    |------ |
| int1              | 990       | 1090  |
| int2              | 1100      | 1150  |
| int3              | 500       | 2000  |

结果应如下所示:

| name  | pos   | interval_name     | start     | end   |
|------ |------ |---------------    |-------    |------ |
| a     | 1020  | int1              | 990       | 1090  |
| a     | 1020  | int3              | 500       | 2000  |
| b     | 1200  | int1              | 990       | 1090  |
| b     | 1200  | int3              | 500       | 2000  |
| c     | 1800  | int3              | 500       | 2000  |

标签: bashjoin

解决方案


免责声明:如果可用,请使用专用/本地工具,这是黑客行为:

您想要的输出中有一个明显的错误: name bshould not match int1

$ tail -n+1 *.csv
==> f1.csv <==
name,pos
a,1020
b,1200
c,1800

==> f2.csv <==
interval_name,start,end
int1,990,1090
int2,1100,1150
int3,500,2000

$ awk -F, -vOFS=, '
  BEGIN {
    print "name,pos,interval_name,start,end"
    PROCINFO["sorted_in"]="@ind_num_asc"
  }
  FNR==1 {next}
  NR==FNR {Int[$1] = $2 "," $3; next}
  {
    for(i in Int) {
      split(Int[i], I)
      if($2 >= I[1] && $2 <= I[2]) print $0, i, Int[i]
    }
  }
' f2.csv f1.csv

输出:

name,pos,interval_name,start,end
a,1020,int1,990,1090
a,1020,int3,500,2000
b,1200,int3,500,2000
c,1800,int3,500,2000

这无论如何都不是特别有效;唯一使用的排序是确保以正确的顺序解析 Int 数组,如果您的示例数据不指示实际模式,则该顺序会发生变化。我很想知道我的解决方案与 pandas 的表现如何。


推荐阅读