您的位置:首页 > 运维架构 > Linux

【Linux】一步一步学Linux——join命令(56)

2019-07-24 10:29 1026 查看
版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

00. 目录

文章目录

01. 命令概述

join命令用来将两个文件中,制定栏位内容相同的行连接起来。找出两个文件中,指定栏位内容相同的行,并加以合并,再输出到标准输出设备。

注意:join在对两个文件进行连接时,两个文件必须都是按照连接域排好序的,按其他域排序是无效的。

02. 命令格式

用法:join [选项]... 文件1 文件2

03. 常用选项

针对每一对具有相同内容的输入行,整合为一行写到标准输出,
默认的内容连接区块是由第一个空白符代表的分界符号。当文件1
或文件2 都被指定为"-"时,程序将从标准输入读取数据。

-a  文件编号          文件编号的值可以是1 或2,分别对应文件1 和 文件2。
此选项用于根据指定文件编号输出不成对的行目。
-e 字符               将缺失的输入区块替换为指定字符
-i, --ignore-case     比较时忽略大小写
-j 域                 等于"-1 域 -2 域"
-o 格式               按照指定格式构造输出行
-t 字符               使用指定字符作为输入和输出的分隔符
-v 文件编号           类似 -a 文件编号,但禁止组合输出行
-1 域                 在文件1 的此域组合
-2 域                 在文件2 的此域组合
--check-order         检查输入行是否正确排序,即使所有输入行均是成对的
--nocheck-order       不检查输入是否正确排序
--header              将首行视作域的头部,直接输出而不对其进行匹配
--help            显示此帮助信息并退出
--version         显示版本信息并退出

除非使用了"-t 字符串" 选项,否则前导空格分隔的域将被忽略,如果指定了字符串,
则使用指定字符串分隔任意的域并从1 开始计数的域编号。可以指定的格式是由一个
或多个逗号活空格所分隔的描述,其形式为"文件编号.域"或者"0"。默认的
格式输出合并后的域、文件1 和文件2 剩下的域,均由该指定字符串分隔。

重要提示:文件1 和文件2 必须在合并域中排序。
例如,如果"join"后没有选项,使用"sort -k 1b,1"。
注意,所进行的比较遵从"LC_COLLATE"所指定的的规则。
如果输入没有被排序并导致某些行无法合并,将会显示警告信息。

04. 参考示例

两个文件内容如下

[deng@localhost test]$ cat file1
1 一月
2 二月
3 三月
4 四月
5 五月
6 六月
7 七月
8 八月
9 九月
10 十月
11 十一月
12 十二月
13 十三月
[deng@localhost test]$ cat file2
1 January
2 February
3 March
4 April
5 May
6 June
7 July
8 August
9 September
10 October
11 November
12 December
14 MonthUnknown
[deng@localhost test]$

4.1 内连接(忽略不匹配的行)

[deng@localhost test]$ join file1 file2
1 一月 January
2 二月 February
3 三月 March
4 四月 April
5 五月 May
6 六月 June
7 七月 July
8 八月 August
9 九月 September
10 十月 October
11 十一月 November
12 十二月 December
[deng@localhost test]$

不指定任何参数的情况下使用join命令,就相当于数据库中的内连接,关键字不匹配的行不会输出。

4.2 左连接(又称左外连接,显示左边所有记录)

[deng@localhost test]$ join -a1 file1 file2
1 一月 January
2 二月 February
3 三月 March
4 四月 April
5 五月 May
6 六月 June
7 七月 July
8 八月 August
9 九月 September
10 十月 October
11 十一月 November
12 十二月 December
13 十三月
[deng@localhost test]$

显示左边文件中的所有记录,右边文件中没有匹配的显示空白。

4.3 右连接(又称右外连接,显示右边所有记录)

[deng@localhost test]$ join -a2 file1 file2
1 一月 January
2 二月 February
3 三月 March
4 四月 April
5 五月 May
6 六月 June
7 七月 July
8 八月 August
9 九月 September
10 十月 October
11 十一月 November
12 十二月 December
14 MonthUnknown
[deng@localhost test]$

显示右边文件中的所有记录,左边文件中没有匹配的显示空白。

4.4 全连接(又称全外连接,显示左边和右边所有记录)

[deng@localhost test]$ join -a1 -a2 file1 file2
1 一月 January
2 二月 February
3 三月 March
4 四月 April
5 五月 May
6 六月 June
7 七月 July
8 八月 August
9 九月 September
10 十月 October
11 十一月 November
12 十二月 December
13 十三月
14 MonthUnknown
[deng@localhost test]$

4.5 指定输出字段

[deng@localhost test]$ join -o 1.1 file1 file2
1
2
3
4
5
6
7
8
9
10
11
12
[deng@localhost test]$

比如参数 -o 1.1 表示只输出第一个文件的第一个字段。

4.6 指定输出多个字段

输出第一个文件的第一个字段,输出第二个文件第二个字段

[d
3ff7
eng@localhost test]$ join -o 1.1 2.2 file1 file2
1 January
2 February
3 March
4 April
5 May
6 June
7 July
8 August
9 September
10 October
11 November
12 December
[deng@localhost test]$

输出第一个文件的第一个字段和第二个字段,输出第二个文件第二个字段

[deng@localhost test]$ join -o 1.1 2.2 1.2 file1 file2
1 January 一月
2 February 二月
3 March 三月
4 April 四月
5 May 五月
6 June 六月
7 July 七月
8 August 八月
9 September 九月
10 October 十月
11 November 十一月
12 December 十二月
[deng@localhost test]$

第一个文件第三个字段不存在的情况

[deng@localhost test]$ join -o 1.1 1.2 1.3 2.2 file1 file2
1 一月  January
2 二月  February
3 三月  March
4 四月  April
5 五月  May
6 六月  June
7 七月  July
8 八月  August
9 九月  September
10 十月  October
11 十一月  November
12 十二月  December
[deng@localhost test]$

4.7 指定分隔符

[root@localhost ~]# join -t ':' /etc/passwd /etc/shadow
root:x:0:0:root:/root:/bin/bash:$6$NYBpPt0OXHSNfdD7$WK6.pQ0CId2ndPYiYWzdi9ZgO1GZd3lwiDrbSEo55ew6PXuG3MxMmlL5M7az3OddWLgZSANP7jFT5T034OmpM/::0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:17632:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:17632:0:99999:7:::
adm:x:3:4:adm:/var/adm:/sbin/nologin:*:17632:0:99999:7:::
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin:*:17632:0:99999:7:::
sync:x:5:0:sync:/sbin:/bin/sync:*:17632:0:99999:7:::
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown:*:17632:0:99999:7:::

4.8 指定了以两个文件中第一列做匹配字段

等同于join file1 file2

[deng@localhost test]$ join  -j1 file1 file2
1 一月 January
2 二月 February
3 三月 March
4 四月 April
5 五月 May
6 六月 June
7 七月 July
8 八月 August
9 九月 September
10 十月 October
11 十一月 November
12 十二月 December
[deng@localhost test]$

4.9 指定匹配的字段

以第一个文件的第二列和第二个文件的第三列做匹配字段。由于第二个文件中第三列的两个3 都与第一个文件中第三行因此输出

[deng@localhost test]$ join -1 1 -2 2 file1 file2
join: file1:10: is not sorted: 10 十月
join: file2:2: is not sorted: 2 February
[deng@localhost test]$

4.10 指定字符串补全

-o 指定 将file1的1,2列,file2的1,2 列都输出。-a指定将file1中不匹配的行也输出,但是file2中没有与file1后两行对应的字段,因此使用empty补齐

[deng@localhost test]$ join -o 1.1 1.2 2.1 2.2 -e 'empty' -a1 file1 file2
1 一月 1 January
2 二月 2 February
3 三月 3 March
4 四月 4 April
5 五月 5 May
6 六月 6 June
7 七月 7 July
8 八月 8 August
9 九月 9 September
10 十月 10 October
11 十一月 11 November
12 十二月 12 December
13 十三月 empty empty
[deng@localhost test]$

4.11 不匹配的行输出

[deng@localhost test]$ join -v 1 -a1 -a2  file1 file2
13 十三月
14 MonthUnknown
[deng@localhost test]$

4.12 结合管道使用

有时我们需要将多个格式相同的文件join到一起,而join接受的是两个文件的指令,此时我们可以使用管道和字符“-"来实现

[deng@localhost test]$ join file1 file2 | join - file2 | join - file1
1 一月 January January 一月
2 二月 February February 二月
3 三月 March March 三月
4 四月 April April 四月
5 五月 May May 五月
6 六月 June June 六月
7 七月 July July 七月
8 八月 August August 八月
9 九月 September September 九月
10 十月 October October 十月
11 十一月 November November 十一月
12 十二月 December December 十二月
[deng@localhost test]$

温馨提示:join命令和数据库中的join命令很类似。

05. 附录

参考:【Linux】一步一步学Linux系列教程汇总

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: