假设我有两个文件,en.csv
and sp.csv
,每个包含恰好两个逗号分隔的记录:
en.csv
:
1,dog,red,car
3,cat,white,boat
sp.csv
:
2,conejo,gris,tren
3,gato,blanco,bote
如果我执行
join -t, -a 1 -a 2 -e MISSING en.csv sp.csv
我得到的输出是:
1,dog,red,car
2,conejo,gris,tren
3,cat,white,boat,gato,blanco,bote
请注意,所有缺失的字段均已折叠。为了获得“正确的”完整外部联接,我需要指定一种格式;因此
join -t, -a 1 -a 2 -e MISSING -o 0,1.2,1.3,1.4,2.2,2.3,2.4 en.csv sp.csv
yields
1,dog,red,car,MISSING,MISSING,MISSING
2,MISSING,MISSING,MISSING,conejo,gris,tren
3,cat,white,boat,gato,blanco,bote
这种生成完整外连接的方法的一个缺点是需要显式指定最终表的格式,这在编程应用程序中可能并不容易做到(其中连接表的标识仅在运行时已知)。
GNU 的最新版本join
通过支持特殊格式消除这个缺点auto
。因此,有了这样的版本join
上面的最后一个命令可以替换为更通用的命令
join -t, -a 1 -a 2 -e MISSING -o auto en.csv sp.csv
我怎样才能用版本达到同样的效果join
不支持-o auto
option?
背景和细节
我有一个 Unix shell (zsh) 脚本,旨在处理多个 CSV 平面文件,并通过以下方式实现:广泛的使用GNUjoin
的“-o auto”选项。我需要修改这个脚本,以便它可以在可用的环境中工作join
命令不支持-o auto
选项(如 BSD 的情况join
以及旧版本的 GNUjoin
).
在脚本中此选项的典型用法如下:
_reccut () {
cols="1,$1"
shift
in=$1
shift
if (( $# > 0 )); then
join -t, -a 1 -a 2 -e 'MISSING' -o auto \
<( cut -d, -f $cols $in | sort -t, -k1 ) \
<( _reccut "$@" )
else
cut -d, -f $cols $in | sort -t, -k1
fi
}
我举这个例子是为了说明它很难被替换-o auto
使用显式格式,因为要包含在此格式中的字段直到运行时才知道。
功能_reccut
上面基本上从文件中提取列,并沿着第一列连接结果表。看看如何_reccut
在行动中,想象一下,除了上面提到的文件之外,我们还有以下文件
de.csv
2,Kaninchen,Grau,Zug
1,Hund,Rot,Auto
然后,例如,并排显示第 3 列en.csv
,第 2 列和第 4 列sp.csv
,并且 de.csv 的第 3 列将运行:
% _reccut 3 en.csv 2,4 sp.csv 3 de.csv | cut -d, 2-
red,MISSING,MISSING,Rot
MISSING,conejo,tren,Grau
white,gato,bote,MISSING