linux/unix命令详解之join

Comments: No Comments
Published on: 2012 年 01 月 09 日

NAME
       join - join lines of two files on a common field

SYNOPSIS
       join [OPTION]... FILE1 FILE2

DESCRIPTION
       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.
       -a FILENUM
              print unpairable lines coming from file FILENUM, where FILENUM is 1 or 2, corresponding to FILE1 or FILE2
       -e EMPTY
              replace missing input fields with EMPTY
       -i, --ignore-case ignore differences in case when comparing fields
       -j FIELD
              equivalent to ‘-1 FIELD -2 FIELD’
       -o FORMAT
              obey FORMAT while constructing output line
       -t CHAR
              use CHAR as input and output field separator
       -v FILENUM
              like -a FILENUM, but suppress joined output lines
       -1 FIELD
              join on this FIELD of file 1
       -2 FIELD
              join on this FIELD of file 2
       --help display this help and exit
       --version
              output version information and exit
功能说明:将两个文件中,指定栏位内容相同的行连接起来。

语  法:join [-i][-a<1或2>][-e<字符串>][-o<格式>][-t<字符>][-v<1或2>][-1<栏位>][-2<栏位>][--help][--version][文件1][文件2]

补充说明:找出两个文件中,指定栏位内容相同的行,并加以合并,再输出到标准输出设备。

参  数:
  -a<1或2>  就是可以 -a1 或者-a2 或者一起用。单独使用一个的话,则根据指定
的文件的关键字段进行连接,即指连接并且显示指定文件有的行。如-a1 即文件1有
的行才把文件2的内容链接过来并显示出来,-a2类似。如果-a1 -a2一起使用,则
两个文件有的行都会显示出来。
  -e<字符串>   若[文件1]与[文件2]中找不到指定的栏位,则在输出中填入选项中
的字符串。
  -i或--igore-case   比较栏位内容时,忽略大小写的差异。
  -o<格式>   按照指定的格式来显示结果。
  -t<字符>   使用栏位的分隔字符。
  -v<1或2>   跟-a相同,但是只显示文件中没有相同栏位的行。
  -1<栏位>   连接[文件1]指定的栏位。
  -2<栏位>   连接[文件2]指定的栏位。
  --help   显示帮助。
  --version   显示版本信息。

需要注意的是,使用join连接两个文件的相关字段,都需要先进行排序。如果连接的主字段有重复,则会导致两个文件相关行的排列组合,请确保这是你需要的结果。
另外如果你想使用-e 选项,需要使用-o选项来格式化列,负责-e是没有效果的。还有一点就是你会发现使用-e -o 进行全连接的话,两个文件的关键列都必须使用上,负责-e会把缺失的关键列那也填补上相应的字符,有时候这并非我们期望的,具体的请自己行试验测试。
个人认为这是join命令的一点瑕疵,他应该两个文件如果全连接或者左连接右连接出现单独的关键键都应该是关键键名称而不是-e补充。不过这个瑕疵可以用awk来弥补一下,倒是挺容易。我的修补代码附在最后。

样例:
现在假设两个文件 j1 , j2 内容如下:
j1:
1 a
2 b
3 c
5 e

j2:
1 A
2 B
5 E
6 F
命令效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ join j1 j2
1 a A
2 b B
5 e E
$ join -a1 j1 j2
1 a A
2 b B
3 c
5 e E
$ join -a2 j1 j2
1 a A
2 b B
5 e E
6 F
$ join -a2 -a1 j1 j2                      
1 a A
2 b B
3 c
5 e E
6 F
$ join -o 1.1,1.2,2.2 j1 j2  #1文件显示第一二列,2文件显示第二列
1 a A
2 b B
5 e E
$ join -1 1 -2 1 j1 j2 #设定关键字段为:1文件的第一个字段和2文件第一字段
1 a A
2 b B
5 e E

代码大意就是以文件1的第一个字段和文件2的第一个字段为关键字段进行全连接。然后awk来处理连接后的主字段合并成一列的善后工作。

1
2
3
4
5
6
7
8
9
10
11
12
join  -a1 -a2  -1 1 -2 1 -e "0" -o 1.1,2.1,1.2,1.3,2.2,2.3  file1 file2 | awk '
        BEGIN{ printf "insert into weibodata (action,count,usercount,backcount,backip,date) values";first=0;}
        {
                if(first!=0)
                        printf ",";
                if($1 !=0)
                        printf "("$1",";
                else printf "("$2",";
                printf $3","$4","$5","$6")";
                first=1;                
        }' date=$dateFlag > $dateFlag"sentBackCount.sql"
'

我猜你可能也喜欢:

No Comments - Leave a comment

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


Welcome , today is 星期六, 2017 年 10 月 21 日