bash 中按列合并行数不等的多个文件的更快方法

Faster way to merge multiple files with unequal number of rows by column in bash

我有多个文件,我想使用 shell 脚本按列合并,假设文件 a.txt 和文件 b.txt。文件 a.txt 包含排序的唯一值,第一列将用作参考值。
示例:

# cat a.txt 
001|johan
002|mike
003|adam
# cat b.txt
001|chu
001|stewart
002|lewis
002|jordan
003|lambert
003|johnson
003|smith
003|long

这两个文件将合并生成如下所示的输出。

# cat c.txt
001|johan chu
001|johan stewart
002|mike lewis
002|mike jordan
003|adam lambert
003|adam johnson
003|adam smith
003|adam long

我尝试使用 while do 进行简单迭代。

while read line
do
  ids=`echo $line | awk -F"|" '{print }'`
  fn=`grep $ids a.txt`
  echo $fn"|"$line | awk -F"|" '{print "|"" "}'
done < b.txt > c.txt

但是如果我有百万行,这会花费很多时间。
MySQL 中,我们可以使用 JOIN 子句轻松实现它。但我们需要先 load/insert 他们。
更快的方法可能是使用 paste 命令,但据我所知,两个文件的总行数必须相等。那我可以先调整a.txt。但是当脚本 运行.
时仍然消耗很多时间 也许有人有更好的方法。

您可以将所有内容放在一个 awk 脚本中:

awk -F'|' '{if (NR==FNR) a[]=; else print  "|" a[] " " }' a.txt b.txt 
001|johan chu
001|johan stewart
002|mike lewis
002|mike jordan
003|adam lambert
003|adam johnson
003|adam smith
003|adam long

假设:

  • 两个文件都按第 1 列排序
  • 忽略在相反文件中没有匹配项的行

使用 joinsed 的一个想法(删除第二个 |):

join -t'|' -o 1.1,1.2,2.2 a.txt b.txt | sed -E 's/\|([^|]*$)/ /'

一个awk想法:

awk '
BEGIN   { FS=OFS="|" }
FNR==NR { a[]=; next }
 in a { print ,a[] " "  }
' a.txt b.txt

这两个生成:

001|johan chu
001|johan stewart
002|mike lewis
002|mike jordan
003|adam lambert
003|adam johnson
003|adam smith
003|adam long