这篇博客,向大家介绍如何使用sort命令进行文本排序,以及如何进行文本统计。希望对你有帮助。
一、使用sort命令对文本排序
在Shell中很多数据是以文本的形式存在,因此,用户经常需要对这些文本进行排序,为此Shell提供了sort命令来完成这个任务。
1. sort命令的基本用法
Shell中sort命令有三种使用模式,分别是排序文本、检查文件是否已经排序以及合并文件,首先介绍一下如何使用sort命令进行文本排序,下面是sort命令的基本语法:
sort [option]... [file]...
在上面的语法中,option表示命令选项,常用的选项如下:
- -b:忽略前导空格或者制表符,找到第一个非空字符。
- -c:测试文件是否已经排好序。
- -d:根据字典顺序排序。该选项仅比较数字、字母和空格等字符。
- -f:忽略大小写。将小写字母转化为大写字母后进行比较。
- -i:仅比较可打印字符。
- -n:根据算数值进行比较,参与比较的字符有空格十进制数字以及减号等。如果对非数字字符进行算数比较,将会产生无法预知的结果。
- -R:根据哈希值随机排序。
- -r:颠倒排序结果。
- -k:定义排序关键字。
- -m:仅仅合并已经排好序的文件,不执行排序操作。
- -o:将排序结果写入文件,而不是标准输出设备。
- -t:指定分段字符。默认值为空格。
- -u:删除重复的行,只保留第一个。
file文件是要排序的文件列表,多个文件名以空格隔开。如果以-作为文件名,则从标准输入读取数据。
下面我们创建一个message.txt文件,内容如下:
[root@random_wz ~]# cat message.txt
Random man 19 100
Hello man 20 200
World woman 18 10
Shell man 20 150
Message man 100 100
我们使用sort命令对message文件进行排序:
[root@random_wz ~]# sort message.txt
Hello man 20 200
Message man 100 100
Random man 19 100
Shell man 20 150
World woman 18 10
我们可以看到sort命令根据第一个字母对文件进行了排序。
2. 使用单个关键字排序
sort命令默认会根据整个文本行进行排序,文本行中的所有列都会参与排序,但是如果我们需要根据某一列进行排序,就需要使用-k参数了,其基本语法如下:
-k pos1[,pos2]
其中pos1表示排序关键字开始的位置,pos2表示结束的位置,两者之间通过空格隔开。
我们对message.txt文件进行排序,指定关键字为第2列和第3列,如果关键字的第一列相同,则会根据关键字的第二个列进行排序,依次类推:
[root@random_wz ~]# sort -k 2,3 message.txt
Message man 100 100
Random man 19 100
Shell man 20 150
Hello man 20 200
World woman 18 10
注意:sort命令中,一个文本行最多只能包含10列。
一般情况下,排序关键字是由起始列和终止列定义的,但是在某些情况下,用户可能会省略终止列,只保留起始列,语法如下:
-k pos
以上语法为一种合法的语法,他表示从pos参数指定的列开始,一直到文本行的结束都是排序的关键字,也就是说,sort命令会从pos指定的列开始进行比较,如果pos列相同则比较后面的列,依次类推。
[root@random_wz ~]# sort -k 2 message.txt
Message man 100 100
Random man 19 100
Shell man 20 150
Hello man 20 200
World woman 18 10
上面的排序结果你可能会觉得奇怪,100比19大但是却排在了前面,这里解释一下,sort命令会将列作为字符串进行排序,100的第一个字符是1,和19的第一个字符相同,但是他的第二个字符0的ASCII值比19的第二个ASCII值小,因此排在了第一个,在后面的内容中我们会介绍如何处理这种情况。
注意:-k pos并不表示以pos列作为关键字进行排序。
有时候我们需要根据指定的字符排序,这就需要用到下面的语法:
-k pos1[.start] [, pos2.[end]]
pos1表示起始的列,start表示起始的列的第一个字符开始数,字符开始的位置,如1.2表示第一列的第二个字符开始,pos2表示结束的列,end为结束列的字符位置。
下面举个例子:
[root@random_wz ~]# cat data.txt
Chinese 100
Englist 200
Math 100
Python 300
[root@random_wz ~]# sort -n -k 2.1,2.3 data.txt
Chinese 100
Math 100
Englist 200
Python 300
-n表示将关键字作为数字进行排序。
3. 根据指定的列排序
根据某个列进行排序的语法如下:
-k pos, pos
可以看到只需要指定开始列和末尾列为同一列即可,我们也可以指定某一列的某些字符进行排序:
-k pos[.start],pos[.end]
这个我们在上面已经用过了,就不举例了。
4. 根据关键字降序排序
前面所有的例子都是升序排序,如果我们要降序排序,就要使用-r命令了,另外r命令还提供了修饰符,用来实现根据关键字降序排列。其中-r选项是作为全局选项使用,其作用对象为sort命令所有妹有附件修饰符的列。修饰符r可以附加在组成关键字的列号后面,其作用域为附加的列。
#下面的语句会依次从左到右进行降序排序。
sort -r -k 2,3 message.txt
#下面的语句会先根据第二列到第三列的值进行降序排序。
sort -k 2,3r message.txt
5. 数值列的排序
之前我们遇到过数值排序的问题,在默认情况下sort命令会把所有关键字作为字符串来进行排序,为了使sort命令可以对数字进行排序,这里我们使用-n参数或者n修饰符。
sort -n -k 2,3 message.txt
#下面的语句会将第二列到三列作为数字进行排序。
sort -k 2,3n message.txt
注意:对于非数字关键字,如果使用-n参数,会导致不可预料的结果。
6.自定义列分隔符
默认情况下sort命令以空格或者制表符作为分隔符。但是在实际情况中,我们的分隔符可能不止空格和制表符。为此sort命令提供了-t选项用来指定分隔符。
sort -t : -k 3n,3 /etc/passwd
注意:我们可以通过-t " "指定以空格作为分隔符。
7.删除重复的行
sort命令提供了-u选项用来去除重复的行。
sort -u message.txt
8.根据多个关键字排序
前面我们介绍了如何使用sort指定关键字进行排序,其实我们除了可以指定一个参数外,还可以通过多次使用-k参数指定关键字进行排序,排序的顺序为从左到右,下面为语法。
sort [option] -k pos1,pos2 -k pos3,pos4,... [file]...
9.使用sort命令合并文件
sort命令可以很方便的进行文件合并,他会先将文件内容进行排序,然后合并,语法如下:
sort file1 file2 ...
file1、file2表示要合并的文件,每个文件名以空格隔开。
如果我们在合并文件的时候希望删除重复的行,则可以通过下面的方式进行文件的合并:
sort -u file1 file2 > result.txt
如果我们不想对文件进行排序,则可以使用下面的方法:
sort -m file1 file2 > result.txt
二、文本的统计
Shell中提供了很多种工具来进行文本的统计,例如wc、cat、grep等,这里介绍一下常用的命令。
1. 输出含有行号的文本行
(1)cat命令
cat命令有一个-n参数该选项会在行首添加行号,如下所示:
[root@random_wz ~]# cat -n demo.txt
1 Random man 19 100
2 Hello man 20 200
3 World woman 18 10
4 Shell man 20 150
5 Message man 10 100
(2)grep命令
grep命令和cat命令类似,他也有一个-n选项用来输出行号,如下所示:
[root@random_wz ~]# cat demo.txt | grep -E "*" -n
1:Random man 19 100
2:Hello man 20 200
3:World woman 18 10
4:Shell man 20 150
5:Message man 10 100
(3)nl命令
nl命令是专门用来添加行号的,语法如下:
nl [option]... [file]...
nl常用选项如下:
- -b:显示风格,可以取a、t及n等值,a表示为所有行添加行号,t表示仅仅为非空行添加行号,n表示不添加行号。
- -i:行号的增量,默认值为1.
- -v:行号的起始值,默认值为1.
参数file表示要添加行号的文件列表。
[root@random_wz ~]# nl -ba demo.txt
1 Random man 19 100
2 Hello man 20 200
3 World woman 18 10
4 Shell man 20 150
5 Message man 10 100
注意:如果不使用-b a选项,则nl命令只编号非空行。
2. 统计行数
grep命令提供了-c选项,用来统计符合文本筛选的文本行的行数,如下所示:
[root@random_wz ~]# cat demo.txt | grep -E "*" -c
5
wc命令是Shell中用来对文本进行各种统计的命令,语法如下:
wc [option]... [file]...
其中,wc命令的常用选项如下:
- -c:统计文本的字节数。
- -m:统计字符数。
- -l:统计行数。
- -L:统计最长行的长度。
- -w:统计单词数。
与其他命令一样,wc命令也可以接收多个文件名作为参数。
[root@random_wz ~]# wc -l demo.txt
5 demo.txt
3. 统计单词书和字符数
在wc命令通过空格来区分单词,使用-w参数可以统计文本中的单词数量,通过-m选项可以统计文本的字符数。
#! /usr/bin/env bash
#统计单词数量,只取的数量
words=`cat demo1.txt | wc -w`
echo "there ara ${words} words in file demo1.txt"
#统计字符数
chars=`cat demo1.txt | wc -m`
echo "there ara ${chars} characters in file demo1.txt"
Output:
[root@random_wz ~]# cat demo.txt
Random man 19 100
Hello man 20 200
World woman 18 10
Shell man 20 150
Message man 10 100
[root@random_wz ~]# sh test.sh
there ara 20 words in file demo.txt
there ara 106 characters in file demo.txt