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

我使用过的Linux命令之join - 根据关键字合并数据文件

2014-08-30 00:18 465 查看
本文链接:http://codingstandards.iteye.com/blog/796299 (转载请注明出处)



用途说明

Linux下最常用的数据文件格式是文本格式的,多个字段之间通过分隔符来区分,分隔符比如冒号(:)、制表符、空格等。/etc/passwd和/etc/group就是用:来分隔的,用MySQL的into outfile指令导出的数据通常是以制表符分隔的。这种文本格式既方便人去阅读,也适合程序处理,通常某列类似于数据库中的关键字。join命令就是一个根据关键字合并数据文件的命令(join lines of two files on a common field),类似于数据库中两张表关联查询。


常用参数

join命令根据公共字段(关键字)来合并两个文件的数据行。因此最简单的使用方式就是指定两个数据文件名,这两个文件的第一列就是公共字段,字段之间以空白分隔。(For each pair of input lines with identical join fields, write a line to standard output. The default join field is the first, delimited by whitespace. When FILE1 or FILE2 (not
both) is -, read standard input.)

内连接(inner join) 格式:join <FILE1> <FILE2>

左连接(left join, 左外连接, left outer join) 格式:join -a1 <FILE1> <FILE2>

右连接(right join, 右外连接,right outer join) 格式:join -a2 <FILE1> <FILE2>

全连接(full join, 全外连接, full outer join) 格式:join -a1 -a2 <FILE1> <FILE2>



指定分隔符:

-t <CHAR>

比如:-t ':' 使用冒号作为分隔符。默认的分隔符是空白。



指定输出字段:

-o <FILENO.FIELDNO> ...

其中FILENO=1表示第一个文件,FILENO=2表示第二个文件,FIELDNO表示字段序号,从1开始编号。默认会全部输出,但关键字列只输出一次。

比如:-o 1.1 1.2 2.2 表示输出第一个文件的第一个字段、第二个字段,第二个文件的第二个字段。



使用示例


示例一 内连接(忽略不匹配的行)

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

[root@rhel55 linux]# cat month_cn.txt

1 一月

2 二月

3 三月

4 四月

5 五月

6 六月

7 七月

8 八月

9 九月

10 十月

11 十一月

12 十二月

13 十三月,故意的

[root@rhel55 linux]# cat month_en.txt

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

注:注意两个文件的内容,中文版的多了十三月,英文版的多了14月,这纯粹是为了方便演示。

[root@rhel55 linux]# join month_cn.txt month_en.txt

1 一月 January

2 二月 February

3 三月 March

4 四月 April

5 五月 May

6 六月 June

7 七月 July

8 八月 August

9 九月 September

10 十月 October

11 十一月 November

12 十二月 December

[root@rhel55 linux]#


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

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

[root@rhel55 linux]# join -a1 month_cn.txt month_en.txt

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 十三月,故意的

[root@rhel55 linux]#



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

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

[root@rhel55 linux]# join -a2 month_cn.txt month_en.txt

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

[root@rhel55 linux]#



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

[root@rhel55 linux]# join -a1 -a2 month_cn.txt month_en.txt

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

[root@rhel55 linux]#



示例五 指定输出字段

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

[root@rhel55 linux]# join -o 1.1 month_cn.txt month_en.txt

1

2

3

4

5

6

7

8

9

10

11

12

[root@rhel55 linux]# join -o 1.1 2.2 month_cn.txt month_en.txt

1 January

2 February

3 March

4 April

5 May

6 June

7 July

8 August

9 September

10 October

11 November

12 December

[root@rhel55 linux]# join -o 1.1 2.2 1.2 month_cn.txt month_en.txt

1 January 一月

2 February 二月

3 March 三月

4 April 四月

5 May 五月

6 June 六月

7 July 七月

8 August 八月

9 September 九月

10 October 十月

11 November 十一月

12 December 十二月

[root@rhel55 linux]# join -o 1.1 2.2 1.2 1.3 month_cn.txt month_en.txt <== 字段1.3并不存在

1 January 一月

2 February 二月

3 March 三月

4 April 四月

5 May 五月

6 June 六月

7 July 七月

8 August 八月

9 September 九月

10 October 十月

11 November 十一月

12 December 十二月

[root@rhel55 linux]#



示例六 指定分隔符

[root@rhel55 linux]# join -t ':' /etc/passwd /etc/shadow

root:x:0:0:root:/root:/bin/bash:$1$K8WSIAfQ$9i1h6a4V1XeIn0lv.CT53/:14833:0:99999:7:::

bin:x:1:1:bin:/bin:/sbin/nologin:*:14833:0:99999:7:::

daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:14833:0:99999:7:::

adm:x:3:4:adm:/var/adm:/sbin/nologin:*:14833:0:99999:7:::

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin:*:14833:0:99999:7:::

sync:x:5:0:sync:/sbin:/bin/sync:*:14833:0:99999:7:::

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown:*:14833:0:99999:7:::

halt:x:7:0:halt:/sbin:/sbin/halt:*:14833:0:99999:7:::

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin:*:14833:0:99999:7:::

news:x:9:13:news:/etc/news::*:14833:0:99999:7:::

uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin:*:14833:0:99999:7:::

operator:x:11:0:operator:/root:/sbin/nologin:*:14833:0:99999:7:::

games:x:12:100:games:/usr/games:/sbin/nologin:*:14833:0:99999:7:::

gopher:x:13:30:gopher:/var/gopher:/sbin/nologin:*:14833:0:99999:7:::

ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin:*:14833:0:99999:7:::

nobody:x:99:99:Nobody:/:/sbin/nologin:*:14833:0:99999:7:::

nscd:x:28:28:NSCD Daemon:/:/sbin/nologin:!!:14833:0:99999:7:::

vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin:!!:14833:0:99999:7:::

rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin:!!:14833:0:99999:7:::

mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin:!!:14833:0:99999:7:::

smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin:!!:14833:0:99999:7:::

pcap:x:77:77::/var/arpwatch:/sbin/nologin:!!:14833:0:99999:7:::

ntp:x:38:38::/etc/ntp:/sbin/nologin:!!:14833:0:99999:7:::

dbus:x:81:81:System message bus:/:/sbin/nologin:!!:14833:0:99999:7:::

avahi:x:70:70:Avahi daemon:/:/sbin/nologin:!!:14833:0:99999:7:::

sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin:!!:14833:0:99999:7:::

rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin:!!:14833:0:99999:7:::

nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin:!!:14833:0:99999:7:::

haldaemon:x:68:68:HAL daemon:/:/sbin/nologin:!!:14833:0:99999:7:::

avahi-autoipd:x:100:101:avahi-autoipd:/var/lib/avahi-autoipd:/sbin/nologin:!!:14833:0:99999:7:::

oprofile:x:16:16:Special user account to be used by OProfile:/home/oprofile:/sbin/nologin:!!:14833:0:99999:7:::

xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin:!!:14833:0:99999:7:::

gdm:x:42:42::/var/gdm:/sbin/nologin:!!:14833:0:99999:7:::

sabayon:x:86:86:Sabayon user:/home/sabayon:/sbin/nologin:!!:14833:0:99999:7:::

oracle:x:500:500::/opt/oracle:/bin/bash:$1$v64Pa.m.$GZMrQiOWCdQPF8XKtWju30:14833:0:99999:7:::

mysql:x:101:104:MySQL server:/var/lib/mysql:/bin/bash:!!:14866::::::

[root@rhel55 linux]#


问题思考

1. 怎样使用join命令实现两个文件中关键字的交集、并集、差集?

2. 怎样使用join命令中指定关键字的列,而非默认的第一列?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: