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



我有多个文件要使用shell脚本按列合并,比如文件a.txt和文件b.txt文件1.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 $1}'`
fn=`grep $ids a.txt`
echo $fn"|"$line | awk -F"|" '{print $1"|"$2" "$4}'
done < b.txt > c.txt

但是如果我有一百万行的话,这需要花费很多时间
MySQL中,我们可以使用JOIN子句轻松地实现它。但我们需要先加载/插入它们
更快的方法可能是使用paste命令,但据我所知,两个文件的总行数必须相等。我可以先调整a.txt。但在剧本运行时仍然需要花费大量时间
也许有人有更好的方法。

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

awk -F'|' '{if (NR==FNR) a[$1]=$2; else print $1 "|" a[$1] " " $2}' 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

假设:

  • 两个文件都按第一列排序
  • 忽略对方文件中不匹配的行

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

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

awk的一个想法:

awk '
BEGIN   { FS=OFS="|" }
FNR==NR { a[$1]=$2; next }
$1 in a { print $1,a[$1] " " $2 }
' 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

相关内容

  • 没有找到相关文章

最新更新