现在的位置: 首页 > 综合 > 正文

linux shell编程指南第十一章————合并与分割

2014年07月26日 ⁄ 综合 ⁄ 共 5734字 ⁄ 字号 评论关闭

有几种工具用来处理文本文件分类、合并和分割操作,本章详细介绍这些工具。
本章内容有:
• 实用的分类(s o r t)操作。
• uniq。
• join。
• cut。
• paste。

• split。

s o r t命令将许多不同的域按不同的列顺序分类。当查阅注册文件或为另一用户对下载文件
重排文本列时, s o r t工具很方便。实际上,使用其他U N I X工具时,已假定工作文件已经被分
过类。无论如何,分类文件比不分类文件看起来更有意义。

U N I X / L I N U X自带的s o r t功能很强大。尽管有时在使用s o r t各种不同的选项时人们已经很
小心,但仍会产生意想不到的结果。s o r t选项很长,甚至有时在各种不同开关的实际功能和结
果进行比较时也会遇到麻烦,原因可能是在结合使用s o r t的不同选项时有些概念模糊不清。

sort选项:

s o r t命令的一般格式为:
sort -cmu -o output_file [other options] +pos1 +pos2 input_files
下面简要介绍一下s o r t的参数:
-c 测试文件是否已经分类。
-m 合并两个分类文件。
-u 删除所有复制行。
-o 存储s o r t结果的输出文件名。

其他选项有:
-b 使用域进行分类时,忽略第一个空格。
-n 指定分类是域上的数字分类。
-t 域分隔符;用非空格或t a b键分隔域。
-r 对分类次序或比较求逆。
+n n为域号。使用此域号开始分类。
n n为域号。在分类比较时忽略此域,一般与+ n一起使用。
post1 传递到m,n。m为域号,n为开始分类字符数;例如4,6意即以第5域分类,从第7
个字符开始。

o选项保存分类结果,然而也可以使用重定向方法保存。下面例子保存结果到r e s u l t s . o u t:

sort   video.txt   >    results.out

缺省情况下, s o r t认为一个空格或一系列空格为分隔符。要加入其他方式分隔,使用- t选项。

s o r t执行时,先查看是否为域分隔设置了- t选项,如果设置了,则使用它来将记录分隔成
域0、域1等等;如果未设置,用空格代替。缺省时s o r t将整个行排序,指定域号的情况例外。
下面是文件v i d e o . t x t的清单,包含了上个季度家电商场的租金情况。各域为:(1)名称,
(2)供货区代码,(3)本季度租金,(4)本年租金。域分隔符为冒号。为此对此例需使用‘ - t’
选项。文件如下:

[root@localhost ~]# cat video.txt 
Boys in Company C:HK:192:2192
Alien:HK:119:1982
The Hill:KL:63:2972
Aliens:HK:532:4892
Star Wars:HK:301:4102
A Few Good Men:KL:445:5851
Toy Story:HK:239:3972

关于s o r t的一个重要事实是它参照第一个域作为域0,域1是第二个域,等等。s o r t也可以使用整行作为分类依据。

s o r t将定位各域,因此应把域0作为分类键0,域1作为分类键1等等。

使用s o r t - c通知s o r t文件是否按某种顺序分类。

基本sort:

最基本的s o r t方式为sort filename,按第一域进行分类(分类键0)。实际上读文件时s o r t操
作将行中各域进行比较,这里返回基于第一域s o r t的结果,如下所示:

[root@localhost ~]# sort -t: video.txt 
A Few Good Men:KL:445:5851
Alien:HK:119:1982
Aliens:HK:532:4892
Boys in Company C:HK:192:2192
Star Wars:HK:301:4102
The Hill:KL:63:2972
Toy Story:HK:239:3972

如果要逆向s o r t结果,使用- r选项。在通读大的注册文件时,使用逆向s o r t很方便。下面是
按域0分类的逆向结果。

[root@localhost ~]# sort -t: -r video.txt 
Toy Story:HK:239:3972
The Hill:KL:63:2972
Star Wars:HK:301:4102
Boys in Company C:HK:192:2192
Aliens:HK:532:4892
Alien:HK:119:1982
A Few Good Men:KL:445:5851

有时需要只按第2域(分类键1)分类。这里为重排报文中供应区代码,使用t 1,意义为
按分类键1分类。下面的例子中,所有供应区代码按分类键1分类;注意分类键2和3对应各域
也被分类。

[root@localhost ~]# sort -t : -k 1 video.txt 
A Few Good Men:KL:445:5851
Alien:HK:119:1982
Aliens:HK:532:4892
Boys in Company C:HK:192:2192
Star Wars:HK:301:4102
The Hill:KL:63:2972
Toy Story:HK:239:3972

要按第三分类键分类,使用t 3。但是因为这是数值域,即为数值分类,可以使用- n选项。下面例子为按年租金分类命令及结果:

[root@localhost ~]# sort -n  -t : -k 3 video.txt 
The Hill:KL:63:2972
Alien:HK:119:1982
Boys in Company C:HK:192:2192
Toy Story:HK:239:3972
Star Wars:HK:301:4102
A Few Good Men:KL:445:5851
Aliens:HK:532:4892

有时,原文件中有重复行,这时可以使用- u选项进行唯一性(不重复)分类以去除重复
行,本例中A l i e n有相同的两行。带重复行的文件如下,其中A l i e n插入了两次:

可以指定分类键次序。先以第2域,再以第1域分类,命令为-k2 -k1,方法如下:

[root@localhost huangcd]# sort -t: -k2 -k1 video.txt 
Alien:HK:119:1982
Boys in Company C:HK:192:2192
Toy Story:HK:239:3972
Star Wars:HK:301:4102
Aliens:HK:532:4892
A Few Good Men:KL:445:5851
The Hill:KL:63:2972

pos用法:

指定开始分类的域位置的另一种方法是使用如下格式:

sort +field_number.characters_in
意即从f i e l d n u m b e r开始分类,但是要在此域的第c h a r a c t e r s i n个字符开始。

要只使用供应区代码后缀部分将文件分类,其命令为-k 1.3 第一个域第三个字符开始排序. ,意即以第1域最左边第3个字
符开始分类,其具体含义及脚本如下:

[root@localhost ~]# sort -t: -k 1.2 video.txt 
Aliens:HK11:532:4892
Star Wars:HK38:301:4102
Boys in Company C:HK48:192:2192
Alien:HK57:119:1982
Toy Story:HK65:239:3972
The Hill:KL23:63:2972
A Few Good Men:KL87:445:5851

分类操作时,不一定要显示整个文件或一页以查看s o r t结果中的第一和最后一行。如果只
显示最高年租金,按第4域分类- k 4并求逆,然后使用管道只显示s o r t输出的第一行,此命令为
h e a d,可以指定查阅行数。如果只有第一行,则为head -1:

[root@localhost ~]# sort -t: -r -k 4  video.txt |head -1
A Few Good Men:KL87:445:5851
[root@localhost ~]# sort -t: -r -k 4  video.txt |tail -1
Alien:HK57:119:1982

awk使用sort输出结果:

对数据分类时,对s o r t结果加一点附加信息很有必要,对其他用户尤其如此。使用a w k可
以轻松完成这一功能。比如说采用上面最低租金的例子,需要将s o r t结果管道输出到a w k,不
要忘了用冒号作域分隔符,显示提示信息和实际数据。

[root@localhost ~]# sort -t: -r  -k 4 video.txt |tail -1|awk -F: '{print "Worst rental",$1,"has been rented"$3}'
Worst rental Alien has been rented119

将两个分类文件合并:

将文件合并前,它们必须已被分类。合并文件可用于事务处理和任何种类的修改操作。
下面这个例子,因为忘了把两个家电名称加入文件,它们被放在一个单独的文件里,现在将
之并入一个文件。分类的合并格式为‘ sort -m sorted_file1 sorted_file2,下面是包含两个新家
电名称的文件列表,它已经分类完毕:

[root@localhost ~]# cat video2.txt 
Crimson Tide:134:2031
Die Hard:152:2981

使用-m +o。将这个文件并入已存在的分类文件v i d e o . s o r t,要以名称域进行分类,实际上
没有必要加入+ o,但为了保险起见,还是加上的好。

[root@localhost huangcd]# sort -t: -m  -k 1  video2.txt  video.txt > video.sort
[root@localhost huangcd]# cat video.sort 
Boys in Company C:HK:192:2192
Alien:HK:119:1982
rimson Tide:134:2031
Die Hard:152:2981
The Hill:KL:63:2972
Aliens:HK:532:4892
Star Wars:HK:301:4102
A Few Good Men:KL:445:5851
Toy Story:HK:239:3972

系统sort:

s o r t可以用来对/ e t c / p a s s w d文件中用户名进行分类。这里需要以第1域即注册用户名分类,
然后管道输出结果到a w k,a w k打印第一域。

[root@localhost ~]# cat /etc/passwd|sort -t:|awk -F ":" '{print $1}'
adm
apache
avahi-autoipd
avahi
bin
daemon
dbus
distcache
dovecot
ftp
games
gdm

s o r t还可以用于d f命令,以递减顺序打印使用列。下面是一般d f输出。

[root@localhost huangcd]# df
文件系统               1K-块        已用     可用 已用% 挂载点
/dev/sda2              5952284   4922364    722680  88% /
/dev/sda3              3968124    309844   3453452   9% /home
/dev/sda1               988088     29216    907868   4% /boot
tmpfs                   364880         0    364880   0% /dev/shm

使用- b选项,忽略分类域前面的空格。使用域4(+ 4),即容量列将分类求逆,最后得出
文件系统自由空间的清晰列表。

[root@localhost huangcd]# df|sort -b -r -k 4|awk '{print $4}'
可用
907868
722680
364880
3453452

uniq用法:

u n i q用来从一个文本文件中去除或禁止重复行。一般u n i q假定文件已分类,并且结果正确。
我们并不强制要求这样做,如果愿意,可以使用任何非排序文本,甚至是无规律行。
可以认为u n i q有点像s o r t命令中唯一性选项。对,在某种程度上讲正是如此,但两者有一
个重要区别。s o r t的唯一性选项去除所有重复行,而u n i q命令并不这样做。重复行是什么?在
u n i q里意即持续不断重复出现的行,中间不夹杂任何其他文本,现举例如下:

[root@localhost ~]# cat myfile.txt 
May Day
May Day
May Day
Going Down
May Day.

u n i q将前三个May Day看作重复副本,但是因为第4行有不同的文本,故并不认为第五行
持续的May Day为其副本。u n i q将保留这一行。

命令一般格式:

uniq  -u d c  -f  input-file   output-file
其选项含义:
-u 只显示不重复行。
-d 只显示有重复数据行,每种重复行只显示其中一行
-c 打印每一重复行出现次数。
-f n为数字,前n个域被忽略。
一些系统不识别- f选项,这时替代使用- n。

使用本节开始时的文本,创建文件m y f i l e . t x t,在此文件上运行u n i q命令。

[root@localhost ~]# uniq myfile.txt 
May Day
Going Down
May Day

注意第5行保留下来,其文本为最后一行May Day。如果运行sort -u,将只返回May Day
和Going Down。

[root@localhost ~]# uniq -u myfile.txt 
Going Down
May Day

使用- c选项显示行数,即每个重复行数目。本例中,行May Day重复出现三次。

[root@localhost ~]# uniq -c myfile.txt 
      3 May Day
      1 Going Down
      1 May Day

使用- d显示重复出现的不唯一行:

[root@localhost huangcd]# uniq -d myfile.txt 
May Day

对特定域进行测试:

如果忽略第1域,只测试第2域唯一性,使用- n 2,下述文件包含一组数据,其中第2域代
表组代码。

如果指定测试在第1域后,结果就会不同。u n i q会比较三个相同的O P,因此将返回一行。

[root@localhost ~]# cat parts.txt 
AK123 op
DK122 op
EK999 op
[root@localhost ~]# uniq -c parts.txt 
      1 AK123 op
      1 DK122 op
      1 EK999 op
[root@localhost ~]# uniq -f 2 parts.txt 
AK123 op

抱歉!评论已关闭.