3.3.3 使用 join 连接字段

    join 命令可以将多个文件结合在一起,每个文件里的每条记录,都共享一个键值(key),键值指的是记录中的主字段,通常会是用户名称、个人姓氏、员工编号之类的数据。举例来说,两个文件,一个列出所有业务员销售业绩,一个列出每个业务员应该实现的业绩:
    
    #业务员   量
    joe       100
    jane      200
    herman 150
    chris       300
 
    #业务员     配额
    joe        50
    jane      75
    herman 80
    chris       95
 
    每条记录都有两个字段:业务员的名字与相对应的量。在本例中,列与列之间有多个空白,从而可以排列整齐。
 
    为了让 join 运作得到正确结果,输入文件必须先完成排序。
 
    #删除注释并排序数据文件
    sed '/^#/d'  quotas  | sort > quotas.sorted
    sed '/^#/d'  sales     | sort > sales.sorted
 
    #以第一个键值作结合,将结果产生至标准输出
    join quotas.sorted  sales.sorted
 
    #删除缓存文件
    rm -f quotas.sorted  sales.sorted
 
    首先,使用 sed 删除注释,然后再排序个别文件。排序后的缓存文件成为 join 命令的输入数据,最后删除缓存文件。最后执行结果如下:
 
    chris      95     300
    herman  80    150
    jane       75     200
    joe         50     100
 
                                                 join
语法
    join  [ options ]  file1  file2 ...
 
用途
    以共同一个键值,将已存储文件内的记录加以结合。
 
主要选项
    -1  filed1
    -2  field2
        标明要结合的字段。-1 field1 指的是从 file1 取出 field1,而 -2 field2 指的则为从 file2 取出 field2.字段编号自 1 开始,而非0。
 
    -o file.field
        输出 file 文件中的 field 字段。一般的字段则不打印。除非使用多个 -o 选项,即可显示多个输出字段。
 
    -t separtor
        使用 separator 作为输入字段分隔字符,而非使用空白。此字段也为输出的字段分隔字符。
 
行为模式
    读取 file1 与 file2 ,并根据共同键值结合多笔记录。默认以空白分隔字段。输出结果则包括共同键值、来自 file1 的其余记录,接着 file2 的其余记录(指除了键值外的记录)。若 file1 为 - ,则 join 会读取标准输入。每个文件的第一个字段是用来结合的默认键值;可以使用 -1 与 -2 更改之。默认情况下,在两个文件中未含键值的行将不打印(已有选项可更改,间 join 手册)
 
警告:
    -1 与 -2 选项的用法是比较新的。在较旧的系统上,可能用得着:-1j field 与 -2j field2。
 
 

补充:
功能说明:将两个文件中,指定栏位内容相同的行连接起来。
 
语  法:join [-i][-a<1或2>][-e<字符串>][-o<格式>] [-t<字符>][-v<1或2>][-1<栏位>][-2<栏位>][--help] [--version][文件1][文件2]
 
补充说明:找出两个文件中,指定栏位内容相同的行,并加以合并,再输出到标准输出设备。
 
参  数:
-a<1或2> 除了显示原来的输出内容之外,还显示指令文件中没有相同栏位的行。
-e<字符串> 若[文件1]与[文件2]中找不到指定的栏位,则在输出中填入选项中的字符串。
-i或--igore-case 比较栏位内容时,忽略大小写的差异。
-o<格式> 按照指定的格式来显示结果。
-t<字符> 使用栏位的分隔字符。
-v<1或2> 跟-a相同,但是只显示文件中没有相同栏位的行。
-1<栏位> 连接[文件1]指定的栏位。
-2<栏位> 连接[文件2]指定的栏位。
--help 显示帮助。
 
--version 显示版本信息。
指定输出字段:
-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
123456789101112
[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::::::
posted @ 2019-01-23 10:03  Avention  阅读(344)  评论(0编辑  收藏  举报