Linux shell编程学习笔记71: sort 命令——构造有序世界_管道

0 前言

在大数据时代,我们面对和使用大量数据,如果数据是有序的,无疑是有益的。

在Linux中,我们可以使用 sort 命令来构造一个有序的空间。

1 sort命令 的功能、格式和选项说明

我们可以使用命令sort --help来获取帮助信息。

[purpleendurer @ bash ~] sort --help
Usage: sort [OPTION]... [FILE]...
  or:  sort [OPTION]... --files0-from=F
Write sorted concatenation of all FILE(s) to standard output.

Mandatory arguments to long options are mandatory for short options too.
Ordering options:

  -b, --ignore-leading-blanks  ignore leading blanks
  -d, --dictionary-order      consider only blanks and alphanumeric characters
  -f, --ignore-case           fold lower case to upper case characters
  -g, --general-numeric-sort  compare according to general numerical value
  -i, --ignore-nonprinting    consider only printable characters
  -M, --month-sort            compare (unknown) < 'JAN' < ... < 'DEC'
  -h, --human-numeric-sort    compare human readable numbers (e.g., 2K 1G)
  -n, --numeric-sort          compare according to string numerical value
  -R, --random-sort           sort by random hash of keys
      --random-source=FILE    get random bytes from FILE
  -r, --reverse               reverse the result of comparisons
      --sort=WORD             sort according to WORD:
                                general-numeric -g, human-numeric -h, month -M,
                                numeric -n, random -R, version -V
  -V, --version-sort          natural sort of (version) numbers within text

Other options:

      --batch-size=NMERGE   merge at most NMERGE inputs at once;
                            for more use temp files
  -c, --check, --check=diagnose-first  check for sorted input; do not sort
  -C, --check=quiet, --check=silent  like -c, but do not report first bad line
      --compress-program=PROG  compress temporaries with PROG;
                              decompress them with PROG -d
      --debug               annotate the part of the line used to sort,
                              and warn about questionable usage to stderr
      --files0-from=F       read input from the files specified by
                            NUL-terminated names in file F;
                            If F is - then read names from standard input
  -k, --key=KEYDEF          sort via a key; KEYDEF gives location and type
  -m, --merge               merge already sorted files; do not sort
  -o, --output=FILE         write result to FILE instead of standard output
  -s, --stable              stabilize sort by disabling last-resort comparison
  -S, --buffer-size=SIZE    use SIZE for main memory buffer
  -t, --field-separator=SEP  use SEP instead of non-blank to blank transition
  -T, --temporary-directory=DIR  use DIR for temporaries, not $TMPDIR or /tmp;
                              multiple options specify multiple directories
      --parallel=N          change the number of sorts run concurrently to N
  -u, --unique              with -c, check for strict ordering;
                              without -c, output only the first of an equal run
  -z, --zero-terminated     end lines with 0 byte, not newline
      --help     display this help and exit
      --version  output version information and exit

KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a
field number and C a character position in the field; both are origin 1, and
the stop position defaults to the line's end.  If neither -t nor -b is in
effect, characters in a field are counted from the beginning of the preceding
whitespace.  OPTS is one or more single-letter ordering options [bdfgiMhnRrV],
which override global ordering options for that key.  If no key is given, use
the entire line as the key.

SIZE may be followed by the following multiplicative suffixes:
% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.

With no FILE, or when FILE is -, read standard input.

*** WARNING ***
The locale specified by the environment affects sort order.
Set LC_ALL=C to get the traditional sort order that uses
native byte values.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report sort translation bugs to <http://translationproject.org/team/>
For complete documentation, run: info coreutils 'sort invocation'
[purpleendurer @ bash ~]
  • 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.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.

Linux shell编程学习笔记71: sort 命令——构造有序世界_排序_02

 

1.1 sort命令的功能

sort命令的功能如其名,就是排序。

sort命令不仅可以用来对文件内容按行进行排序处理,而且可以配合其他命令一起使用,对命令的输出结果进行排序处理。

特别是uniq命令,uniq命令要求输入的数据必须经过排序。

1.2 sort命令的格式

有两种格式。

1.2.1 sort命令的格式1

sort [选项]... [文件]...

1.2.2 sort命令的格式2

 sort [选项]... --files0-from=F

1.3 sort命令的选项说明

 sort命令的选项分为排序选项和其他选项两类。

1.3.1 sort命令的排序选项

选项

说明

-b, --ignore-leading-blanks

忽略每行前面开始出的空格字符

-d, --dictionary-order

排序时只考虑空格和字母数字字符

-f, --ignore-case

排序时忽略字母大小写

-g, --general-numeric-sort

按一般数值比较

-i, --ignore-nonprinting

排序时只考虑可打印字符

-M, --month-sort

将前面3个字母依照月份的缩写来进行排序。

-h, --human-numeric-sort

比较人类可读的数字(例如,2K 1G)

-n, --numeric-sort

根据字符串数值进行比较

-R, --random-sort

按键的随机哈希排序

--random-source=文件名

从指定文件中获取随机字节

-r, --reverse

以相反的顺序来排序

--sort=字

按指定字代表的类型来进行排序:

指定字:通用数字 -g,人文数字 -h,月份 -M,数字 -n,随机 -R,版本 -V

-V, --version-sort

文本中(版本)数字的自然排序

1.3.2 sort命令的其他选项

选项

说明

--batch-size=NMERGE

一次合并最多 NMERGE 输入;如需更多,请使用临时文件

-c, --check, --check=diagnose-first

检查输入是否已排序;不排序

-C, --check=quiet, --check=silent

类似-c,但不报告第一个无序行

--compress-program=程序名称

使用指定程序压缩临时文件;使用该程序的-d 参数解压缩文件

--debug

为用于排序的行添加注释,并将有可能有问题的用法输出到标准错误输出

--files0-from=文件名

从指定文件读取以NUL 终止的名称,如果该文件被指定为"-"则从标准输入读文件名

-k, --key=KEYDEF

通过键进行排序;KEYDEF 要给出位置和类型

-m, --merge

合并已排序的文件;不排序

-o, --output=FILE

将结果写入到文件而非标准输出

-s, --stable

禁用last-resort 比较以稳定比较算法

-S, --buffer-size=SIZE

指定主内存缓存大小

-t, --field-separator=分隔符

使用指定的分隔符代替非空格到空格的转换

-T, --temporary-directory=目录

使用指定目录而非$TMPDIR 或/tmp 作为临时目录,可用多个选项指定多个目录

--parallel=N

将同时运行的排序数改变为N

-u, --unique

与-c配合时,严格校验排序;不与-c配合时,则只输出一次排序结果

-z, --zero-terminated

行结束符为 NUL,而不是换行符

--help

显示此帮助信息并退出

--version

显示版本信息并退出

2 sort命令的使用实例

2.1 创建演示文件

我们先创建两个演示用的文件。

2.1.1 创建演示文件ta.txt
[purpleendurer @ bash ~] echo -e "Windows95 1995 June\nWindows98 1998 August\nDOS 1981 May" > ta.txt
[purpleendurer @ bash ~] cat ta.txt
Windows95 1995 June
Windows98 1998 August
DOS 1981 May
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 

Linux shell编程学习笔记71: sort 命令——构造有序世界_linux_03

2.1.2 创建演示文件tb.txt
[purpleendurer @ bash ~] echo -e "Debian 1998 November\nUbuntu 1999 December\nGentoo 2002 February" > tb.txt
[purpleendurer @ bash ~] cat tb.txt
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

Linux shell编程学习笔记71: sort 命令——构造有序世界_管道_04

2.2 以默认方式对文件内容进行排序并输出排序结果: sort 文件

2.2.1 sort ta.txt
[purpleendurer @ bash ~] cat ta.txt
Windows95 1995 June
Windows98 1998 August
DOS 1981 May
[purpleendurer @ bash ~] sort ta.txt
DOS 1981 May
Windows95 1995 June
Windows98 1998 August
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

Linux shell编程学习笔记71: sort 命令——构造有序世界_学习笔记_05

通过对比文件的原始内容以及sort命令排序后的内容,我们可以发现,排序之后, 原来位于第3行的DOS 1981 May排到了第1行。这是因为 D < W,而且Windows95 < Windows 98。

2.2.2 sort tb.txt
[purpleendurer @ bash ~] cat tb.txt
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~] sort tb.txt
Debian 1998 November
Gentoo 2002 February
Ubuntu 1999 December
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

Linux shell编程学习笔记71: sort 命令——构造有序世界_学习笔记_06

通过对比文件的原始内容以及sort命令排序后的内容,我们可以发现,排序之后, 原来的第2行Ubuntu 1999 December和 第3行Gentoo 2002 February对掉了位置。这是因为 D < G < U。

总结一下:

sort 命令默认方式是将文本文件的第一列以 ASCII 码的次序排列,并将结果输出到标准输出。

2.3 以相反的顺序来排序:sort /r 文件

2.3.1 sort /r ta.txt
[purpleendurer @ bash ~] cat ta.txt
Windows95 1995 June
Windows98 1998 August
DOS 1981 May
[purpleendurer @ bash ~] sort -r ta.txt
Windows98 1998 August
Windows95 1995 June
DOS 1981 May
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

Linux shell编程学习笔记71: sort 命令——构造有序世界_学习笔记_07

 

 通过对比文件的原始内容以及sort /r 命令排序后的内容,我们可以发现,排序之后, 原来位于第2行的Windows98 1998 August和位于第1行的Windows95 1995 June对换了位置。

2.3.2 sort /r tb.txt
[purpleendurer @ bash ~] cat tb.txt
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~] sort -r tb.txt
Ubuntu 1999 December
Gentoo 2002 February
Debian 1998 November
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

Linux shell编程学习笔记71: sort 命令——构造有序世界_排序_08

 通过对比文件的原始内容以及sort /r 命令排序后的内容,我们可以发现,排序之后, 3行内容的位置都有变动,按照首列字母由大到小排列:U > G > D。

2.4 随机排序 :sort -R 文件

以tb.txt文件为例。

在默认情况下,以第1列为进行随机排序。

[purpleendurer @ bash ~] cat tb.txt
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~] sort -R tb.txt
Debian 1998 November
Gentoo 2002 February
Ubuntu 1999 December
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

 

Linux shell编程学习笔记71: sort 命令——构造有序世界_学习笔记_09

 通过对比可以发现,第2行和第3行对换了位置。

如果我们指定以第2列来进行随机排序,结果又会是怎样的呢?

[purpleendurer @ bash ~] cat tb.txt
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~] sort -R -k 2 tb.txt
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~] sort -R -k 2 tb.txt
Gentoo 2002 February
Ubuntu 1999 December
Debian 1998 November
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Linux shell编程学习笔记71: sort 命令——构造有序世界_linux_10

可以看到,两次随机排序的结果并不相同。

2.5 将前面3个字母依照月份的缩写来进行排序:sort -M 文件

我们先看看ta.txt的排序结果。

[purpleendurer @ bash ~] cat ta.txt
Windows95 1995 June
Windows98 1998 August
DOS 1981 May
[purpleendurer @ bash ~] sort -k 3 ta.txt
Windows98 1998 August
Windows95 1995 June
DOS 1981 May
[purpleendurer @ bash ~] sort -k 3 -M ta.txt
DOS 1981 May
Windows95 1995 June
Windows98 1998 August
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

 

Linux shell编程学习笔记71: sort 命令——构造有序世界_sort_11

当我们使用命令sort -k 3 ta.txt 来指定按第3 列排序时,第1行和第2行做了对换,这是因为按照第3列的首字母:A < J < M。

当我们使用命令sort -k 3 -M ta.txt 来指定按第3 列排序时,第1行和第3行做了对换,这是因为按照第3列前3个字母依照月份的缩写:May(5月)< June(6月) < August(8月)。

对于tb.txt,排序结果如下:

[purpleendurer @ bash ~] cat tb.txt
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~] sort -k 3 tb.txt
Ubuntu 1999 December
Gentoo 2002 February
Debian 1998 November
[purpleendurer @ bash ~] sort -k 3 -M tb.txt
Debian 1998 November
Gentoo 2002 February
Ubuntu 1999 December
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

 

Linux shell编程学习笔记71: sort 命令——构造有序世界_排序_12

 

2.5 多个文件内容排序输出: sort [选项] 文件1 文件2……

我们以ta.txt 和tb.txt来例。

[purpleendurer @ bash ~] sort ta.txt tb.txt
Debian 1998 November
DOS 1981 May
Gentoo 2002 February
Ubuntu 1999 December
Windows95 1995 June
Windows98 1998 August
[purpleendurer @ bash ~] sort -k 3 ta.txt tb.txt
Windows98 1998 August
Ubuntu 1999 December
Gentoo 2002 February
Windows95 1995 June
DOS 1981 May
Debian 1998 November
[purpleendurer @ bash ~] sort -k 3 -M ta.txt tb.txt
Debian 1998 November
DOS 1981 May
Gentoo 2002 February
Ubuntu 1999 December
Windows95 1995 June
Windows98 1998 August
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

Linux shell编程学习笔记71: sort 命令——构造有序世界_管道_13

可以看到,我们给sort命令使用的选项不同,排序的结果也不同。

2.6 利用输出重定向将排序结果保存到文件: sort [选项] 文件1 文件2…… > 文件3

我们还可以使用命令sort -k 2 ta.txt tb.txt > tab.txt 将文件 ta和txt tb按照第2列的排序结果保存到文件tab.txt。

[purpleendurer @ bash ~] sort -k 2 ta.txt tb.txt > tab.txt
[purpleendurer @ bash ~] cat tab.txt
DOS 1981 May
Windows95 1995 June
Windows98 1998 August
Debian 1998 November
Ubuntu 1999 December
Gentoo 2002 February
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

Linux shell编程学习笔记71: sort 命令——构造有序世界_sort_14

2.7 对其他命令的输出结果进行排序:其他命令 |  sort [选项]

我们可以利用管道操作来对其他命令的输出结果进行排序输出。

我们以对ls命令的输出结果进行排序输出为例。

[purpleendurer @ bash ~] ls
Code  tab.txt  ta.txt  tb.txt
[purpleendurer @ bash ~] ls | sort
Code
tab.txt
ta.txt
tb.txt
[purpleendurer @ bash ~] ls | sort -V
Code
ta.txt
tab.txt
tb.txt
[purpleendurer @ bash ~]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Linux shell编程学习笔记71: sort 命令——构造有序世界_管道_15

 可以看到,我们给sort命令指定的选项不同,排序的结果也不同。