linux中join命令可以对两个相关联表格的文件以某一列为key进行连接。与sql数据库的join概念类似。
- Inner join
- Left, right, outer join
- 指定Key
- 指定输出的列
- 其它选项
内连接 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 分隔符 指定读取文件时的分隔符