Linux命令:连接表格 join

linux中join命令可以对两个相关联表格的文件以某一列为key进行连接。与sql数据库的join概念类似。

  1. Inner join
  2. Left, right, outer join
  3. 指定Key
  4. 指定输出的列
  5. 其它选项

内连接 Inner join

join 默认以第一列为key进行合并,并输出两个文件都有的行(内连接,inner join),最简单的用法如下所示 :

(**注意使用join前应当对要连接的文件使用sort事先进行排序)

$ cat file1.txt 
1 apple
2 banana
3 pear
4 orange

$ cat file2.txt 
1 pear x
2 apple y
3 banana z
5 kiwi q

$ join file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z

各种连接的概念示意图:

左/ 右 / 外连接 Left/right/outer join

-a N 输出指定第N个文件的所有行

通过-a选项可以完成left join,right join以及outer join的操作

单独指定-a 1 即为左连接(连接后输出第一个文件里所有的行)

单独指定 -a 2 即为右链接(连接后输出第二个文件里所有的行)

同时制定 -a 1 -a 2 为外连接(连接后输出两个文件里所有的行)

#left join
$ join -a 1 file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z
4 orange

#right join
$ join -a 2 file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z
5 kiwi q

#outer join
$ join -a 1 -a 2 file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z
4 orange
5 kiwi q

Key

join默认使用的key是第一列,

-j N 指定两个文件j合并时所使用的key为第N列

也可以单独指定:

-1 N 指定第一个文件所用key为第N列

-2 N 指定第一个文件所用key为第N列

-e [字符串] 指定的key不存在时,输出“字符串”代替

#因为没有以第二列为key进行排序,所以报错
$ join -j 2 file1.txt file2.txt 
join: file1.txt:4: is not sorted: 4 orange
join: file2.txt:2: is not sorted: 2 apple y
pear 3 1 x

#使用<(your command) 形式可以直接将 your command的结果作为输入
#使用排序后的结果则可以以第二列为key合并
join -j 2 <(sort -k 2 file1.txt)  <(sort -k 2 file2.txt)
apple 1 2 y
banana 2 3 z
pear 3 1 x

#-j 2的效果等同 -1 2 -2 2
join -1 2 -2 2 <(sort -k 2 file1.txt)  <(sort -k 2 file2.txt)
apple 1 2 y
banana 2 3 z
pear 3 1 x

#也可以使用-1 与-2 单独指定

#指定的key不存在时,输出“na”代替
$ join -j 4 -e na file1.txt file2.txt 
na 1 apple 1 pear x
na 1 apple 2 apple y
na 1 apple 3 banana z
na 1 apple 5 kiwi q
na 2 banana 1 pear x
na 2 banana 2 apple y
na 2 banana 3 banana z
na 2 banana 5 kiwi q
na 3 pear 1 pear x
na 3 pear 2 apple y
na 3 pear 3 banana z
na 3 pear 5 kiwi q
na 4 orange 1 pear x
na 4 orange 2 apple y
na 4 orange 3 banana z
na 4 orange 5 kiwi q

Output 指定输出的列

-o 选项可以指定输出的列

格式如下:

单列: ”文件序号.列序号“ ,如 1.1 为第1个文件的第1列

多列:“文件序号.{列序号1,列序号1…}” , 如1.{1,2} 为第1个文件的第1列与第2列

#join后输出第1个文件的第1列,与输出第2个文件的第1列
$ join -o 1.1 2.1 file1.txt file2.txt 
1 1
2 2
3 3
#join后输出第1个文件的第1列,与输出第2个文件的第1,2列
$ join -o 1.1 2.{1,2} file1.txt file2.txt
1 1 pear
2 2 apple
3 3 banana

其他常用的选项

-i 匹配时忽略大小写
--header 将第一行视为header,不进行匹配
-v [指定文件名] 输出与指定文件不一致的行
-t 分隔符 指定读取文件时的分隔符

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

您正在使用您的 WordPress.com 账号评论。 注销 /  更改 )

Twitter picture

您正在使用您的 Twitter 账号评论。 注销 /  更改 )

Facebook photo

您正在使用您的 Facebook 账号评论。 注销 /  更改 )

Connecting to %s