sort[1] 命令是 Linux/Unix 系统中用于对文本文件内容进行排序的强大工具。它支持多种排序规则(字母序、数值序、版本序等),可以按指定字段排序,并支持合并已排序文件、检查排序状态等功能。
基本功能:
基本语法:
sort [选项] [文件]
如果没有指定文件,sort 会从标准输入读取数据,这在管道操作中特别有用。
一、快速入门
让我们从最简单的例子开始。假设我们有一个文件 names.txt,内容如下:
CharlieAliceBobDavid
1. 默认排序(字母顺序)
sort names.txt
输出:
AliceBobCharlieDavid
发生了什么?
2. 保存排序结果
sort names.txt > sorted_names.txt
或者使用 -o 选项:
sort names.txt -o sorted_names.txt
3. 处理多个文件
sort file1.txt file2.txt > combined_sorted.txt
这会将两个文件的内容合并后一起排序。
4. 理解排序规则
sort 默认使用本地语言环境(locale)的排序规则。但有一个重要的例外:它区分大小写。
重要概念:在 ASCII 码表中:
这意味着:
- 'A' (65) < 'Z' (90) < 'a' (97) < 'z' (122)
- 'Apple' < 'Zebra' < 'apple' < 'zebra'
创建文件 test.txt:
appleZebraApplezebra1apple10apples2apples
运行:
sort test.txt
结果如下:
10apples1apple2applesAppleZebraapplezebra
二、常用选项详解
1. 数值排序:-n 选项
当处理包含数字的数据时,我们需要使用数值排序:
# 默认排序(字符串排序)$ echo -e "10\n2\n30" | sort10230# 数值排序$ echo -e "10\n2\n30" | sort -n21030
2. 逆序排序:-r 选项
按相反顺序排列:
$ echo -e "10\n2\n30" | sort -nr30102
3. 不区分大小写:-f 选项
默认情况下:
$ sort << EOFApplebananaappleBananaEOF# 输出AppleBananaapplebanana
忽略大小写差异:
sort -f << EOFApplebananaappleBananaEOF# 输出AppleappleBananabanana
4. 去重:-u 选项
只保留唯一的行:
sort -uf << EOFApplebananaappleBananaEOF# 输出Applebanana
5. 检查是否已排序:-c 选项
这在脚本中很有用:
if sort -c file.txt; thenecho"文件已排序"elseecho"文件未排序"fi
静默版本(只返回状态码,不输出错误信息):
sort -C file.txt
三、按列排序
这是 sort 最强大的功能之一。我们先准备一个示例文件 students.txt:
Alice 25 90Bob 30 85Charlie 8 95David 28 88
三列分别对应 name, age, score。
1. 按指定列排序
# 按第2列(年龄)排序sort -k 2 students.txt
等等!这样排序正确吗?让我们看看输出:
Alice 25 90David 28 88Bob 30 85Charlie 8 95
正确的数值排序:
sort -k 2n students.txt
现在输出正确了:
Charlie 8 95Alice 25 90David 28 88Bob 30 85
--debug 选项可以清楚的看到排序依据的字段内容。
$ sort -k 2n --debug students.txtCharlie 8 95 _____________Alice 25 90 _____________David 28 88 _____________Bob 30 85 ___________
2. 理解 -k 选项的语法
-k 选项的完整语法格式为:
-k FStart[.CStart][opts][,FEnd[.CEnd][opts]]
| | |
|---|
FStart | | -k 2 |
.CStart | | -k 2.3 |
FEnd | | -k 2,4 |
.CEnd | | -k 2.3,4.5 |
opts | | -k 2n |
常见用法示例:
# 按第2列数值排序sort -k 2n file.txt# 按第2列数值降序sort -k 2nr file.txt# 按第2列第3个字符开始排序sort -k 2.3 file.txt# 按第2列到第4列排序sort -k 2,4 file.txt# 按第2列第3个字符到第4列第5个字符sort -k 2.3,4.5 file.txt# 多级排序:先按第2列,再按第3列sort -k 2 -k 3 file.txt
重要规则:
另外,可以通过指定 --debug 选项来查看排序用的的字段值。
# 指定从第一列的第三个字符开始 至 第一列结束sort -k 1.3,1 --debug students.txtCharlie 8 95 _________________Bob 30 85 __________Alice 25 90 ______________David 28 88 ______________
如果不指定结束字段:
# 指定从第一列的第三个字符开始至行尾$ sort -k 1.3 --debug students.txtCharlie 8 95 ______________________Bob 30 85 ________________Alice 25 90 ____________________David 28 88 ____________________
3. 指定字段分隔符:-t 选项
默认分隔符是空白字符(空格或制表符)。如果是其他分隔符,需要明确指定:
# 逗号分隔的文件$ cat students.csvAlice,25,90Bob,30,85Charlie,22,95
# 按第3列(分数)数值排序$ sort -t ',' -k 3n students.csvBob,30,85Alice,25,90Charlie,22,95
通过 --debug 验证下 -t 选项:
$ sort -t ',' -k 3n --debug students.csvBob,30,85 ___________Alice,25,90 _____________Charlie,22,95 _______________
不指定 -t:
$ sort -k 3n --debug students.csvAlice,25,90 ^ no match for key___________Bob,30,85 ^ no match for key_________Charlie,22,95 ^ no match for key_____________
4. 多级排序
可以指定多个排序键,按优先级排序:
# 先按年龄降序,年龄相同再按成绩升序sort -k 2nr -k 3n students.txt
输出:
Bob 30 85David 28 88Alice 25 90Charlie 8 95
注意:排序选项(如 n、r)可以附加在字段后面,并且只影响该字段。
四、特殊类型的排序
1. 人性化数字排序:-h 选项
处理人类可读的大小格式(如 1K、2M、3G):
cat sizes.txt1K2M500K1Gsort -h sizes.txt
输出:
1K500K2M1G
2. 月份排序:-M 选项
cat months.txtJanMarFebDecsort -M months.txt
输出:
JanFebMarDec
3. 版本号排序:-V 选项
这是处理软件版本号的利器:
cat versions.txt1.2.31.10.02.0.01.2.10sort -V versions.txt
输出:
1.2.31.2.101.10.02.0.0
注意:-n 无法正确处理版本号,因为它会把点当作小数点。
五、高级功能
1. 稳定排序:-s 选项
当两个记录的所有排序键都相等时,保持它们在原始文件中的相对顺序。
# 输入文件cat stable.txtAlice A 90Bob A 85Charlie B 90David B 85
# 使用稳定排序$ sort -s -k 2 stable.txtBob A 85Alice A 90David B 85Charlie B 90
2. 合并已排序文件:-m 选项
比重新排序快得多,但要求输入文件已排序:
sort -m sorted1.txt sorted2.txt
3. 处理包含空格的文件名
# 安全处理包含空格的文件名find . -name "*.txt" -print0 | sort -z | xargs -0 cat
六、性能优化技巧
1. 设置缓冲区大小
# 为大型文件分配更多内存sort -S 2G large_file.txt
2. 指定临时目录
当 /tmp 空间不足时:
sort -T /mnt/big_disk/temp/ huge_file.txt
3. 使用多线程
# 使用4个线程并行排序sort --parallel=4 big_file.txt
4. 压缩临时文件
# 使用gzip压缩临时文件sort --compress-program=gzip huge_file.txt
最佳实践
- 明确指定字段范围:
-k 2,2 而不是 -k 2 - 大文件要优化: 使用
-S、-T、--parallel
在实际工作中,如果对排序结果不确定,可以使用 --debug 选项查看 sort 是如何解析和比较每行的,这能帮助你理解为什么得到了特定的排序结果。
参考资料
[1] sort: https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html