根据 2 个文件的 2 列中的字符串连接行

根据 2 个文件的 2 列中的字符串连接行

我在 Linux 系统上有一个包含 3 列的 file1 和一个包含 4 列的 file2。如何根据 file1 第 3 列中的字符串将两个文件连接到 file2 第 2 列中的字符串? File2 是一个包含许多条目的大型数据库。 file1 和 file2 的第 3 列和第 2 列分别仅共享很少的字符串。我想输出 file1 和连接的 file2 行,以防字符串匹配,并为不匹配的条目输出破折号。

文件1:

300 100 a101
450 410 a400
670 710 a20
700 610 a340

文件2:

b30  a340 tttttttt 456
b500 a200 llllllll 567
b60  a101 uuuuuuuu 344
b40  a50  kkkkkkkk 223

输出:

300 100 a101 b60 a101 uuuuuuuu 344
450 410 a400 -
670 710 a20  -
700 610 a340 b30 a340 tttttttt 456

答案1

使用 GNUawk和 GNU join,这是 Linux 上的标准(可能会或可能不会与非 GNU 版本一起使用):

$ join -a1 -1 3 -2 2 <(sort -k3,3 file1) <(sort -k2,2 file2) | 
    awk '$4 == "" { $4 = "-" }; {t=$1; $1=$2; $2=$3; $3=t; print}' |
    sort
300 100 a101 b60 uuuuuuuu 344
450 410 a400 -
670 710 a20 -
700 610 a340 b30 tttttttt 456

join命令分别在字段 3 和 2 上连接 file1 和 file2。它使用流程替代确保两个文件都按各自的关键字段排序。-a 1使用该选项可以file1打印来自 的所有行,即使它们与来自 的行不匹配file2

不幸的是,join将 file1 的关键字段放在每个记录的开头。通过使用一个名为 $1 的值的临时持有者的awk变量将字段移回其原始顺序来修复此问题。t如果文件之间不匹配,awk 脚本还会在字段 $4 中添加尾部破折号字符(因为join它本身不执行此操作)。

最后,对输出进行排序。

相关内容