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.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 ~]
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 ~]
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 ~]
通过对比文件的原始内容以及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 ~]
通过对比文件的原始内容以及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 ~]
通过对比文件的原始内容以及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 ~]
通过对比文件的原始内容以及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 ~]
通过对比可以发现,第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 ~]
可以看到,两次随机排序的结果并不相同。
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 ~]
当我们使用命令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 ~]
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 ~]
可以看到,我们给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 ~]
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 ~]
可以看到,我们给sort命令指定的选项不同,排序的结果也不同。