`
wode66
  • 浏览: 742638 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux的sort命令

阅读更多

sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分钟搞定sort,现在开始!

1 sort的工作原理

 

sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。

[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear

2 sort的-u选项

它的作用很简单,就是在输出行中去除重复行。

[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear

pear由于重复被-u选项无情的删除了。

3 sort的-r选项

sort默认的排序方式是升序,如果想改成降序,就加个-r就搞定了。

[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1

4 sort的-o选项

由于sort默认是把结果输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile。

但是,如果你想把排序结果输出到原文件中,用重定向可就不行了。

[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,竟然将number清空了。

就在这个时候,-o选项出现了,它成功的解决了这个问题,让你放心的将结果写入原文件。这或许也是-o比重定向的唯一优势所在。

[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1

5 sort的-n选项

你有没有遇到过10比2小的情况。我反正遇到过。出现这种情况是由于排序程序将这些数字按字符来排序了,排序程序会先比较1和2,显然1小,所以就将10放在2前面喽。这也是sort的一贯作风。

我们如果想改变这种现状,就要使用-n选项,来告诉sort,“要以数值来排序”!

[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19

6 sort的-t选项和-k选项

如果有一个文件的内容是这样:

[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4

这个文件有三列,列与列之间用冒号隔开了,第一列表示水果类型,第二列表示水果数量,第三列表示水果价格。

那么我想以水果数量来排序,也就是以第二列来排序,如何利用sort实现?

幸好,sort提供了-t选项,后面可以设定间隔符。(是不是想起了cut和paste的-d选项,共鸣~~)

指定了间隔符之后,就可以用-k来指定列数了。

[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3

我们使用冒号作为间隔符,并针对第二列来进行数值升序排序,结果很令人满意。

7 其他的sort常用选项

-f会将小写字母都转换为大写字母来进行比较,亦即忽略大小写

-c会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1

-C会检查文件是否已排好序,如果乱序,不输出内容,仅返回1

-M会以月份来排序,比如JAN小于FEB等等

-b会忽略每一行前面的所有空白部分,从第一个可见字符开始比较。

有时候学习脚本,你会发现sort命令后面跟了一堆类似-k1,2,或者-k1.2 -k3.4的东东,有些匪夷所思。今天,我们就来搞定它—-k选项!

1 准备素材

$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500

 

第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。(除了公司名称,其他的别信,都瞎写的^_^)

2 我想让这个文件按公司的字母顺序排序,也就是按第一个域进行排序:(这个facebook.txt文件有三个域)

$ sort -t ‘ ‘ -k 1 facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500

看到了吧,就直接用-k 1设定就可以了。(其实此处并不严格,稍后你就会知道)

3 我想让facebook.txt按照公司人数排序

$ sort -n -t ‘ ‘ -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

不用解释,我相信你能懂。

但是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?按照默认规矩,是从第一个域开始进行升序排序,因此baidu排在了sohu前面。

4  我想让facebook.txt按照公司人数排序 ,人数相同的按照员工平均工资升序排序:

$ sort -n -t ‘ ‘ -k 2 -k 3 facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

看,我们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序。(如果你愿意,可以一直这么写下去,设定很多个排序优先级)

5 我想让facebook.txt按照员工工资降序排序,如果员工人数相同的,则按照公司人数升序排序:(这个有点难度喽)

$ sort -n -t ‘ ‘ -k 3r -k 2 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

此处有使用了一些小技巧,你仔细看看,在-k 3后面偷偷加上了一个小写字母r。你想想,再结合我们上一篇文章,能得到答案么?揭晓:r和-r选项的作用是一样的,就是表示逆序。因为sort默认是按照升序排序的,所以此处需要加上r表示第三个域(员工平均工资)是按照降序排序。此处你还可以加上n,就表示对这个域进行排序时,要按照数值大小进行排序,举个例子吧:

$ sort -t ‘ ‘ -k 3nr -k 2n facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

看,我们去掉了最前面的-n选项,而是将它加入到了每一个-k选项中了。

6 -k选项的具体语法格式

要继续往下深入的话,就不得不来点理论知识。你需要了解-k选项的语法格式,如下:

[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]

这个语法格式可以被其中的逗号(“,”)分为两大部分,Start部分和End部分。

先给你灌输一个思想,那就是“如果不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但往往你不会重视它。

Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start。

C.Start也是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 2和-k 3就是省略了C.Start的例子喽。

FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。

同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。

7 突发奇想,从公司英文名称的第二个字母开始进行排序:

$ sort -t ‘ ‘ -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000

看,我们使用了-k 1.2,这就表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu因为第二个字母是a而名列榜首。sohu和 google第二个字符都是o,但sohu的h在google的o前面,所以两者分别排在第二和第三。guge只能屈居第四了。

8 又突发奇想,,只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序:

$ sort -t ‘ ‘ -k 1.2,1.2 -k 3,3nr facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。(如果你问“我使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于员工工资进行排 序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序” 了。

9 在modifier部分还可以用到哪些选项?

可以用到b、d、f、i、n 或 r。

其中n和r你肯定已经很熟悉了。

b表示忽略本域的签到空白符号。

d表示对本域按照字典顺序排序(即,只考虑空白和字母)。

f表示对本域忽略大小写进行排序。

i表示忽略“不可打印字符”,只针对可打印字符进行排序。(有些ASCII就是不可打印字符,比如\a是报警,\b是退格,\n是换行,\r是回车等等)

10 思考思考关于-k和-u联合使用的例子:

$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500

这是最原始的facebook.txt文件。

$ sort -n -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

$ sort -n -k 2 -u facebook.txt
guge 50 3000
baidu 100 5000
google 110 5000

当设定以公司员工域进行数值排序,然后加-u后,sohu一行就被删除了!原来-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。

$ sort  -k 1 -u facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500

$ sort  -k 1.1,1.1 -u facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500

这个例子也同理,开头字符是g的guge就没有幸免于难。

$ sort -n -k 2 -k 3 -u facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

咦!这里设置了两层排序优先级的情况下,使用-u就没有删除任何行。原来-u是会权衡所有-k选项,将都相同的才会删除,只要其中有一级不同都不会轻易删除的:)(不信,你可以自己加一行sina 100 4500试试看)

11 最诡异的排序:

$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。

第一行,会提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。

又因为sort认为0小于00小于000小于0000….

因此0 3肯定是在第一个。10 5肯定是在最后一个。但为什么00 5却在00 4前面呢?(你可以自己做实验思考一下。)

答案揭晓:原来“跨域的设定是个假象”,sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。当然baidu在sohu前面了。用一个范例即可证实:

$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

12 有时候在sort命令后会看到+1 -2这些符号,这是什么东东?

关于这种语法,最新的sort是这么进行解释的:

On older systems, `sort’ supports an obsolete origin-zero syntax `+POS1 [-POS2]‘ for specifying sort keys.  POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k’ instead.

原来,这种古老的表示方式已经被淘汰了,以后可以理直气壮的鄙视使用这种表示方法的脚本喽!

(为了防止古老脚本的存在,在这再说一下这种表示方法,加号表示Start部分,减号表示End部分。最最重要的一点是,这种方式方法是从0开始计数的,以前所说的第一个域,在此被表示为第0个域。以前的第2个字符,在此表示为第1个字符。明白?)

分享到:
评论

相关推荐

    linux sort命令参数及用法详解.docx

    Linux sort 命令参数及用法详解 Linux sort 命令是一个功能强大且实用的命令行工具,用于对文本文件的内容进行排序。sort 命令的主要功能是将文本文件的内容按照指定的顺序进行排序,以行为单位进行排序。 语法:...

    linux sort命令的用法

    在Linux系统中,`sort`命令是一个非常实用且强大的文本处理工具,主要用于对文本文件中的行进行排序。根据给定的文件信息,我们将深入探讨`sort`命令的多个功能选项,以及它们如何帮助用户更有效地管理和操作数据。 ...

    Linux sort命令用法详解

    Linux sort命令 Linux sort命令用于将文本文件内容加以排序。 sort可针对文本文件的内容,以行为单位来排序。 语法 sort [-bcdfimMnr][-o][-t][+-][--help][--verison][文件] 参数说明: -b 忽略每行前面开始出的...

    linux下uniq和sort命令用法详解.docx

    Linux 下 uniq 和 sort 命令用法详解 uniq 命令是 Linux 中的一个文本处理命令,用于去除文本中的重复行。该命令读取输入文件,并比较相邻的行。在正常情况下,第二个及以后更多个重复行将被删去,行比较是根据所用...

    linux之sort

    Linux 之 sort 命令详解 Linux 之 sort 命令是 Linux 中一个非常有用的命令,用于对文本文件中的数据进行排序。sort 命令可以根据不同的数据类型进行排序,例如按照字母顺序、数字顺序、日期顺序等。 sort 命令的...

    linux ps 命令详解

    **Linux `ps` 命令详解** 在Linux操作系统中,`ps`(Process Status)命令是用于查看系统当前进程状态的工具。它能够显示进程的实时信息,帮助用户了解系统的运行情况,进行进程管理。`ps`命令历史悠久,功能强大,...

    Linux网络操作系统基础:文件处理wc、sort和diff命令.pptx

    Linux 文件处理命令 - wc、sort 和 diff 命令 Linux 操作系统中,文件处理是日常维护和管理中非常重要的一部分。wc、sort 和 diff 命令是 Linux 中三个非常有用的文件处理命令,本文将详细介绍这三个命令的使用方法...

    linux下uniq和sort命令用法.docx

    Linux 下 uniq 和 sort 命令用法 uniq 命令是 Linux 中的一个文本处理命令,用于删除或显示文本文件中的重复行。它可以读取输入文件,并比较相邻的行。在正常情况下,第二个及以后更多个重复行将被删去,行比较是...

    linux常用命令集合

    Linux操作系统以其稳定性和灵活性在IT领域占据着重要地位,学习和掌握Linux常用命令是成为熟练的系统管理员或开发者的基础。以下是一些常见的Linux命令及其详细解释: 1. **Ctrl+u**:清除当前行的输入。 2. **命令...

    Linux命令学习+Linux标准文本处理命令

    通过学习这些基本的Linux命令和Shell操作,初学者可以更快地熟悉Linux环境,并能有效地管理和操作Linux系统。此外,掌握这些技能还有助于提升在开发、运维以及其他与Linux相关的领域的专业能力。

    Linux常用命令 Linux TXT

    ### Linux常用命令详解 #### 一、登录与用户管理 **1. login** - **功能描述**:`login` 命令用于用户登录到 Linux 系统。 - **基本语法**:`login [选项]` - `[name]` 指定用户名。 - `[p]` 如果指定了该选项...

    Linux 常用命令 Linux 常用命令

    Linux 常用命令 Linux 操作系统提供了许多实用的命令,以下是其中的一些: 1. tar 命令:创建和管理 tar 文件 tar 命令用于创建和管理 tar 文件。tar 文件是一种存档文件格式,用于存储和传输文件。tar 命令可以...

    linux 常用命令源代码

    3. `sort.c`: `sort`命令对输入数据进行排序。源代码包含了复杂的数据处理逻辑,如比较函数、内存管理和快速排序算法。这对于学习算法和数据结构有很好的参考价值。 4. `copy.c`: 可能是实现`cp`命令的一部分,用于...

    Linux中用Sort和Tsort对文件进行排序

    Linux 中的 Sort 和 Tsort 命令是两种功能强大且灵活的命令行工具,用于对文件进行排序和处理。Sort 命令可以对文件中的行进行排序、合并文件、查看是否需要排序等操作,而 Tsort 命令则可以对文件中的行进行拓扑...

    linux 核心命令源码

    linux 核心命令源码(cp mv cat chgrp chown cut date df du echo env expand expr find force fs group head hostname join kill link ls mkdir mv nice od paste printf ptx rm selinux seq sleep sort split stat...

    Linux命令大全(CHM格式离线版)

    Linux命令大全(CHM格式离线版) Linux命令大全(修改版) 进行重新编译的说明 文件传输 bye ftp ftpcount ftpshut ftpwho ncftp tftp uucico uucp uupick uuto 备份压缩 ar bunzip2 bzip2 bzip2recover compress cpio ...

    LINUX处理文本命令

    LINUX处理文本命令 处理文本和文本文件的命令 一. sort 文件排序, 通常用在管道中当过滤器来使用. 这个命令可以依据指定的关键字或指定的... 这个命令经常出现在sort命令的管道后边. 四. expand, unexpand ... ...

    Linux ps命令详解

    Linux ps 命令详解 Linux ps 命令是一种强大的进程查看命令,可以确定有哪些进程正在运行、进程是否结束、进程是否僵死、哪些进程占用了过多的资源等等。ps 命令最经常使用的是用于监控后台进程的工作情况,因为...

    Linux 核心命令速查手册

    2. 文本处理命令,如`cat`, `grep`, `awk`, `sed`, `sort`等,用于查看、搜索、筛选、排序和文本处理。 3. 系统管理命令,如`ps`, `top`, `kill`, `nice`, `nohup`等,用于监控和管理正在运行的进程。 4. 网络管理...

Global site tag (gtag.js) - Google Analytics