shell 如何实现两个表的join操作
今天研究的一个问题是:在Shell 脚本中如何实现两个表的 join 操作,这里说的两个表示的其实是 两个文件,但是文件是列表的形式,有固定的分割符号,即就相当于hive中一个非分区表的文件。
表的操作当然是在数据库中操作是最好的: 比如有: table1 table2,我们需要根据 column1 主键关联
select * from table1 a table2 b where a.column1 = b.column1
搞定。如果需要复杂一点的,可以用 join 操作实现。
但是如果你手上刚好有两个文件呢?一种办法是导入数据库,这样太慢了,下面用shell命令实现。
数据样例
- 假设 table1.txt 文件的样例数据如下:
daacdaaedyWcMIV= http://mp.weixin.qq.com/s?__biz=daacdaaedyWcMIV=&mid=200664912&idx=1&sn=c3fbe92847655211faf109c6856f4c0a
daacddeMdcedauY= http://mp.weixin.qq.com/s?__biz=daacddeMdcedauY=&mid=200435227&idx=1&sn=a8802c19dacf0b2db6462eaec09c0b19
daacddeVdeaudaY= http://mp.weixin.qq.com/s?__biz=daacddeVdeaudaY=&mid=200668153&idx=1&sn=869b00b38caa70de6c32848f396b8aa6
daacdduydVWyeMM= http://mp.weixin.qq.com/s?__biz=daacdduydVWyeMM=&mid=200659749&idx=1&sn=6fe9107dd69dd3b5de32bf6e5597a408
daacdeMddMMyVWw= http://mp.weixin.qq.com/s?__biz=daacdeMddMMyVWw=&mid=200912280&idx=7&sn=a70041d29f6b4ad06554ea97291d06bc
daacdMcadMMyduV= http://mp.weixin.qq.com/s?__biz=daacdMcadMMyduV=&mid=200654058&idx=3&sn=a6e57a52b1bd9c38f392825da34b499d
daacdudVdIecyMY= http://mp.weixin.qq.com/s?__biz=daacdudVdIecyMY=&mid=200382730&idx=4&sn=aeed567f2ad4ee595846623f7e2c8fbf
daacduyudeVeWdv= http://mp.weixin.qq.com/s?__biz=daacduyudeVeWdv=&mid=200468183&idx=1&sn=df3d20eef948571d3120b74416b9b010
daacdycIdWdyaIV= http://mp.weixin.qq.com/s?__biz=daacdycIdWdyaIV=&mid=200839908&idx=8&sn=40eb71efc2e70a779af0fc782ac78c47
daacdyIydayccyV= http://mp.weixin.qq.com/s?__biz=daacdyIydayccyV=&mid=200303209&idx=1&sn=63fbd789967812b16ff71b3667d36095```
- table2.txt 文件的样例数据如下:
MjM5MDQ3MDIyMg==
MjM5MDU2OTI4OQ==
MjM5MDc5MTk2NQ==
MjM5MDg5MDE2Nw==
MjM5MDk3NDQ4Mw==
MjM5MTA4MTEyNQ==
MjM5MTQwMzcwMA==
MjM5MjEwMjkyMA==
MjM5MjM2ODU5Nw==
MjM5MjMxOTYxMw==
下面的任务就是要找出table1.txt中所有主键存在于table2.txt中的记录,文件的主键都是第一列
shell命令
awk -F'\t' ' {if (ARGIND==1) ccc[$1]} {if (ARGIND>1 && ($1 in ccc)) print $0} ' test2.txt test1.txt > test.txt
命令解释: awk -F 表示字段分割符号
接下来是命令,命令必须用单引号包围,双引号不行。
ARGIND == 1表示读取到第一个文件,就把第一列存入数组ccc
当读到其他文件,这里就是第二个文件,就判断它的第一列是否在数组中,在就输出。
结束语
为什么选择用shell命令实现这个功能呢?我发现我数据量在一个文件700m,另一个文件30m的情况下,
只需要一分钟出结果,不必数据库慢很多,比其他工具,如R语言快太多,R语言还可能跑不了, 数据分析工作者适当的掌握几个有用的shell工具,如grep、awk、goin等,事半功倍。