假设我有两个文件, en.csv
和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
产量
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
选项?
背景和细节
我有一个设计来处理几个CSV flatfiles,并广泛利用GNU的这样做Unix外壳(zsh中)脚本join
的‘-o自动’选项。 我需要修改这个脚本,以便它可以在现有的环境中工作, join
命令不支持-o auto
选项(如对于BSD的情况下join
以及旧版本的GNU的join
)。
一个典型的使用脚本中的选项是这样的:
_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