5 文件的排序合并和分割.docx
《5 文件的排序合并和分割.docx》由会员分享,可在线阅读,更多相关《5 文件的排序合并和分割.docx(34页珍藏版)》请在冰点文库上搜索。
![5 文件的排序合并和分割.docx](https://file1.bingdoc.com/fileroot1/2023-6/1/80e16790-b38a-405d-b00f-bf5dff60b7a6/80e16790-b38a-405d-b00f-bf5dff60b7a61.gif)
5文件的排序合并和分割
5文件的排序、合并和分割
5.1、sort命令
Linux的sort命令是一种对文件排序的工具,sort命令的功能十分强大,是Shell脚本编程时常用的文件排序工具。
sort命令将输入文件看做由多条记录组成的数据流,而记录由可变宽度的字段组成,以换行符作为定界符。
sort命令与awk一样,可将记录分成多个域进行处理,默认的域分隔符是空格符,当然,域分隔符也可由用户指定其他符号。
sort命令的基本格式为:
sort[选项][输入文件]
sort命令选项及其意义:
-c#测试文件是否已经被排序
-k#指定排序的域
-m#合并两个已排序的文件
-n#根据数字大小进行排序
-o[输出文件]#将输出写到指定的文件,相当于将输出重定向到指定文件
-r#将排序结果逆向显示
-t#改变域分隔符
-u#去除结果中的重复行
5.1.1、sort命令的基本用法
1、-t选项
sort命令是分域对文件进行排序的,默认的域分隔符是空格符,-t选项可用于设置分隔符。
例:
sort命令用-t选项设置分隔符
执行:
catCATGO.db
结果:
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
HongKong:
10000:
2008:
T400
ThinkPad:
USA:
8000:
2007:
X60
HP:
China:
5600:
2010:
DM3
HP:
China:
12000:
2010:
NE808
SumSung:
Korea:
5400:
2009:
Q308
IdeaPad:
China:
8000:
2007:
U450
Acer:
Taiwan:
8000:
2010:
PT210
执行:
sort-t:
CATGO.db#以默认方式对CATGO.db文件排序
结果:
Acer:
Taiwan:
8000:
2010:
PT210
HP:
China:
12000:
2010:
NE808
HP:
China:
5600:
2010:
DM3
IdeaPad:
China:
8000:
2007:
U450
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
HongKong:
10000:
2008:
T400
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
8000:
2007:
X60
sort命令对文件进行排序时用-t选项指定域分隔符为冒号,注意,-t与“:
”之间是没有空格的。
sort命令默认根据第1域对记录进行排序,如果第1域相同,再根据第2域排序,以此类推。
当未指定-t时,分隔符是空格符,这时记录内开头与结尾的空格都将被忽略;当用-t选项改变分隔符时,空格符变得有意义。
例:
空格符:
root:
空格符
对于这条数据记录,若不指定-t选项,这条记录只有一个域,为:
root:
,记录前后的空格符都被忽略了;若用-t选项指定冒号,这条记录就包含了三个域,第1和第3域是空格符,第2域是:
root:
。
2、-k选项
sort命令默认情况下是按第1域进行排序的,也可以按指定某个域进行排序,-k选项就是用于指定域的。
例:
sort命令用-k选项指定排序的域号
执行:
sort-t:
-k3CATGO.db#根据第3域对CATGO.db排序
结果:
ThinkPad:
HongKong:
10000:
2008:
T400
HP:
China:
12000:
2010:
NE808
ThinkPad:
USA:
14000:
2009:
X301
SumSung:
Korea:
5400:
2009:
Q308
HP:
China:
5600:
2010:
DM3
IdeaPad:
China:
8000:
2007:
U450
ThinkPad:
USA:
8000:
2007:
X60
Acer:
Taiwan:
8000:
2010:
PT210
命令利用-k3指定了第3域,注意,-k和3之间也没有空格,从命令的执行结果可以看出,尽管第3域是数字,但是sort命令并未以数字大小来排序,而是仍然以字符串方式进行排序的。
3、-n选项
如果需要根据域的数字大小从小到大的方式对文件进行排序,则需要使用-n选项,-n选项可以指定根据数字大小进行排序。
例:
sort命令用-n选项设置根据数值大小排序
执行:
sort-t:
-k3nCATGO.db#根据第3域的数字大小排序
结果:
SumSung:
Korea:
5400:
2009:
Q308
HP:
China:
5600:
2010:
DM3
Acer:
Taiwan:
8000:
2010:
PT210
IdeaPad:
China:
8000:
2007:
U450
ThinkPad:
USA:
8000:
2007:
X60
ThinkPad:
HongKong:
10000:
2008:
T400
HP:
China:
12000:
2010:
NE808
ThinkPad:
USA:
14000:
2009:
X301
-n选项不是单独使用的,一般放在域号之后。
4、-r选项
-r选项用于将排序结果逆向显示。
如果需要根据域的数字大小从大到小的方式对文件进行排序,就可以利用-n选项先对文件排序,然后用-r选项将结果逆向显示。
例:
sort命令用-r选项将排序结果逆向
执行:
sort-t:
-k3nrCATGO.db
结果:
ThinkPad:
USA:
14000:
2009:
X301
HP:
China:
12000:
2010:
NE808
ThinkPad:
HongKong:
10000:
2008:
T400
Acer:
Taiwan:
8000:
2010:
PT210
IdeaPad:
China:
8000:
2007:
U450
ThinkPad:
USA:
8000:
2007:
X60
HP:
China:
5600:
2010:
DM3
SumSung:
Korea:
5400:
2009:
Q308
5、-u选项
-u选项用于去除排序结果中的重复行。
例:
sort命令-u选项的用法
执行:
catCARGO.db
结果:
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
HongKong:
10000:
2008:
T400
ThinkPad:
USA:
8000:
2007:
X60
HP:
China:
5600:
2010:
DM3
HP:
China:
12000:
2010:
NE808
SumSung:
Korea:
5400:
2009:
Q308
SumSung:
Korea:
5400:
2009:
Q308
IdeaPad:
China:
8000:
2007:
U450
Acer:
Taiwan:
8000:
2010:
PT210
执行:
sort-t:
CARGO.db#根据第1域对CARGO.db排序
结果:
Acer:
Taiwan:
8000:
2010:
PT210
HP:
China:
12000:
2010:
NE808
HP:
China:
5600:
2010:
DM3
IdeaPad:
China:
8000:
2007:
U450
SumSung:
Korea:
5400:
2009:
Q308#重复记录
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
HongKong:
10000:
2008:
T400
ThinkPad:
USA:
14000:
2009:
X301#重复记录
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
8000:
2007:
X60
执行:
sort-t:
-uCARGO.db#利用-u选项对CARGO.db排序
结果:
Acer:
Taiwan:
8000:
2010:
PT210
HP:
China:
12000:
2010:
NE808
HP:
China:
5600:
2010:
DM3
IdeaPad:
China:
8000:
2007:
U450
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
HongKong:
10000:
2008:
T400
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
8000:
2007:
X60#重复记录已经去除
执行:
sort-t:
-k3n-uCARGO.db#根据第3域对文件进行排序
结果:
SumSung:
Korea:
5400:
2009:
Q308
HP:
China:
5600:
2010:
DM3
ThinkPad:
USA:
8000:
2007:
X60
ThinkPad:
HongKong:
10000:
2008:
T400
HP:
China:
12000:
2010:
NE808
ThinkPad:
USA:
14000:
2009:
X301
6、-o选项
sort命令默认将排序后的结果输出到屏幕上,如果需要将结果保存到另一个文件中,则可以使用-o选项加上文件名来完成。
例:
sort命令-o选项的用法
#将CATGO.db按第3域的数值大小排序,并将排序结果存储到SORT_CATGO.db文件
执行:
sort-t:
-k3n-oSORT_CATGO.dbCATGO.db
catSORT_CATGO.db
结果:
SumSung:
Korea:
5400:
2009:
Q308
HP:
China:
5600:
2010:
DM3
Acer:
Taiwan:
8000:
2010:
PT210
IdeaPad:
China:
8000:
2007:
U450
ThinkPad:
USA:
8000:
2007:
X60
ThinkPad:
HongKong:
10000:
2008:
T400
HP:
China:
12000:
2010:
NE808
ThinkPad:
USA:
14000:
2009:
X301
实际上,-o选项的功能与Shell提供的I/O重定向功能一样。
7、-c选项
-c选项用于测试文件是否已经排好序。
例:
sort命令-c选项的用法
#测试CATGO.db是否按默认方式排序
执行:
sort-t:
-cCATGO.db
结果:
sort:
CATGO.db:
2:
无序:
ThinkPad:
HongKong:
10000:
2008:
T400
#测试SORT_CATGO.db是否按默认方式排序
执行:
sort-t:
-cSORT_CATGO.db
结果:
sort:
SORT_CATGO.db:
2:
无序:
HP:
China:
5600:
2010:
DM3
#测试SORT_CATGO.db是否按第3域的数值大小排序
执行:
sort-t:
-k3n-cSORT_CATGO.db
结果:
当该文件已经按这种方式排好序之后,Shell不提示任何信息。
8、-m选项
-m选项用于将两个排好序的文件合并成一个排好序的文件,在文件合并前,它们必须已经排好序。
-m选项对未排序的文件合并是没有任何意义的。
例:
sort命令-m选项的用法
执行:
catCATGO2.db
结果:
DELL:
USA:
6700:
2009:
XPS
MACBOOK:
USA:
10198:
2010:
MB991ZP/A
执行:
sort-t:
-oSORT_CATGO.dbCATGO.db
catSORT_CATGO.db
结果:
Acer:
Taiwan:
8000:
2010:
PT210
HP:
China:
12000:
2010:
NE808
HP:
China:
5600:
2010:
DM3
IdeaPad:
China:
8000:
2007:
U450
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
HongKong:
10000:
2008:
T400
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
8000:
2007:
X60
执行:
sort-t:
-mCATGO2.dbSORT_CATGO.db#合并两个文件
结果:
Acer:
Taiwan:
8000:
2010:
PT210
DELL:
USA:
6700:
2009:
XPS#来自于catCATGO2.db文件
HP:
China:
12000:
2010:
NE808
HP:
China:
5600:
2010:
DM3
IdeaPad:
China:
8000:
2007:
U450
MACBOOK:
USA:
10198:
2010:
MB991ZP/A#来自于catCATGO2.db文件
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
HongKong:
10000:
2008:
T400
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
8000:
2007:
X60
5.1.2、sort和awk的联合用法
sort和awk都是分域处理文件的工具,两者结合起来可以有效地对文本块进行排序。
例:
文本块是指由多行记录组合而成的数据块。
执行:
catPROFESSOR.db
结果:
JLuo
SoutheastUniversity
Nanjing,China
YZhang
VictoryUniversity
Melbourne,Australia
DHou
BeijingUniversity
Beijing,China
BLiu
ShanghaiJiaotongUniversity
Shanghai,China
CLin
UniversityofToronto
Toronto,Canada
例:
利用sort和awk实现文件块的排序
执行:
catPROFESSOR.db|awk-vRS=""'{gsub("\n","@");print}'|sort|awk-vORS="\n\n"'{gsub("@","\n");print}'
#awk-vRS=""'{gsub("\n","@");print}'|#将每个文件块合并到一行
#sort|#对每行的记录排序
#awk-vORS="\n\n"'{gsub("@","\n");print}'#将排序后的行分块打印
结果:
BLiu
ShanghaiJiaotongUniversity
Shanghai,China
CLin
UniversityofToronto
Toronto,Canada
DHou
BeijingUniversity
Beijing,China
JLuo
SoutheastUniversity
Nanjing,China
YZhang
VictoryUniversity
Melbourne,Australia
cat命令将PROFESSOR.db文件的内容作为第1条awk命令的输入数据,该awk命令将每个文件块合并到一行,并用gsub函数将换行符替换成@符号,例如,PROFESSOR.db的第一个文件块将变为“JLuo@SoutheastUniversity@Nanjing,China@”,sort命令对这种格式的记录进行排序,默认以第1域排序,并将排序后的行作为第2条awk命令的输入数据,第2条awk命令执行与第1条awk相反的功能,它将并为一行的数据划分为类似于PROFESSOR.db中的文件块输出,实现方法是用gsub函数将@符号替换成换行符。
5.2、uniq命令
uniq命令用于去除文本文件中的重复行,这类似于sort命令的-u选项,但是,uniq命令和sort-u是存在一些区别的。
例:
uniq命令的基本用法
执行:
catCATGO3.db
结果:
ThinkPad:
USA:
14000:
2009:
X301#重复三行
ThinkPad:
USA:
14000:
2009:
X301
ThinkPad:
USA:
14000:
2009:
X301
HP:
China:
5600:
2010:
DM3
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
USA:
14000:
2009:
X301#隔了几行,再重复一次
IdeaPad:
China:
8000:
2007:
U450
Acer:
Taiwan:
8000:
2010:
PT210
Acer:
Taiwan:
8000:
2010:
PT210
执行:
uniqCATGO3.db#用uniq命令去除重复行
结果:
ThinkPad:
USA:
14000:
2009:
X301#已经去除重复行
HP:
China:
5600:
2010:
DM3
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
USA:
14000:
2009:
X301#该行没有被去除
IdeaPad:
China:
8000:
2007:
U450
Acer:
Taiwan:
8000:
2010:
PT210
执行:
sort-uCATGO3.db#用sort-u去除重复行
结果:
Acer:
Taiwan:
8000:
2010:
PT210
HP:
China:
5600:
2010:
DM3
IdeaPad:
China:
8000:
2007:
U450
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
USA:
14000:
2009:
X301#所有的重复行都被去除
所以,uniq命令去除的重复行必须是连续重复出现的行,中间不能夹杂任何其他文本行。
uniq命令选项及其意义:
-c#打印每行在文本中重复出现的次数
-d#只显示有重复的记录,每个重复记录只出现一次
-u#只显示没有重复的记录
uniq命令-c选项的用法
执行:
uniq-cCATGO3.db
结果:
3ThinkPad:
USA:
14000:
2009:
X301
1HP:
China:
5600:
2010:
DM3
1SumSung:
Korea:
5400:
2009:
Q308
1ThinkPad:
USA:
14000:
2009:
X301
1IdeaPad:
China:
8000:
2007:
U450
2Acer:
Taiwan:
8000:
2010:
PT210
例:
uniq命令-d选项的用法
执行:
uniq-dCATGO3.db#显示有重复的记录
结果:
ThinkPad:
USA:
14000:
2009:
X301
Acer:
Taiwan:
8000:
2010:
PT210
例:
uniq命令-u选项的用法
执行:
uniq-uCATGO3.db#显示没有重复的记录
结果:
HP:
China:
5600:
2010:
DM3
SumSung:
Korea:
5400:
2009:
Q308
ThinkPad:
USA:
14000:
2009:
X301
IdeaPad:
China:
8000:
2007:
U450
例:
统计文本中单词出现的次数
#!
/bin/bash
ARGS=1
E_BADARGS=55
E_NOFILE=56
#以下的if/then结构用于判断执行脚本时是否带了输入参数(即需要统计的文件名),如
果未带输入参数,则返回55错误码
if[$#-ne"$ARGS"]
then
echo"Usage:
'basename$0'filename"
exit$E_BADARGS
fi
#以下的if/then结构用于判断在当前目录下,输入的文件名是否存在,若该文件不存在,
则返回56错误码
if[!
-f"$1"]
then
echo"File\"$1\"doesnotexits."
exit$E_NOFILE
fi
#以下是统计文本单词数的核心命令,sed命令用于过滤句号、逗号、分号,当然可继续
加上需要过滤的符号;sed命令的第4个-e选项将单词间的空格转化为换行符;sort对
sed过滤后的结果排序,每行一个单词;uniq-c输出重复行出现的次数,sort-nr按照
出现频率从大到小排序
sed-e's/\.//g'-e's/\,//g'-e's/\:
//g'-e's//\n/g'"$1"|sort|uniq-c|
sort-nr
exit0
执行:
./count_word.sh#不带输入参数
结果:
Usage:
'basename./count_word.sh'filename
执行:
./count_word.shhh#带先文件名不存在
结果:
File"hh"doesnotexits.
执行:
catWORDLIST
结果:
hello,caicai.world:
watch,worldcaicaihellomessage
messageworldwatchhellointotheheshelastinto.
lastsavehellocaicai,world:
message.
执行:
./count_word.shWORDLIST#统计出WORDLIST中所有的单词出现的次数
结果:
4world
4hello
3message
3caicai
2watch
2last
2into
1the
1she
1save
1he
5.3、join命令
join命令用于实现两个文件中记录的连接操作,连接操作是关系数据库中的概念。
连续操作将两个文件中具有相同域的记录选择出来,再将这些记录所有的域放到一行(包含来自两个文件的所有域)。
例:
join命令的基本用法
执行:
catTEACHER.db
结果:
BLiu:
ShanghaiJiaotongUniversity:
Shanghai:
China
CLin:
UniversityofToronto:
Toronto:
Canada
DHou:
BeijingUniversity:
Beijing:
China
JLuo:
SoutheastUniversity:
Nanjing:
China
YZhang:
VictoryUniversity:
Melbourne:
Australia
执行:
catTEACHER_HOBBY.db
结果:
BLiu:
Tea
CLin:
Song
JCao:
Pingpong
QCai:
Shopping
YZhang:
Photograhy
ZWu:
Chess
#下面执行join操作,将域分隔符改成冒号
执行:
join-t:
TEACHER.dbTEACHER_HOBBY.db
结果:
BLiu:
ShanghaiJiaotongUniversity:
Shanghai:
China:
Tea
CLin:
Uni