我有多个文件要使用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
假设:
- 两个文件都按第一列排序
- 忽略对方文件中不匹配的行
使用join
和sed
(去除第二个|
(的一个想法:
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