一、字典序 vs 数值序
字典序(按字符逐位比较):
1
10
2
20
3
数值序:
1
2
3
10
20
字典序比较的是字符编码,10 的第一位 1 小于 2,所以排在前面。这对「编号、版本号、金额」往往是错的。
判断标准:这一列是不是「数字」?是就用数值序,否则用字典序。
二、大小写与符号
ASCII 里大写字母排在小写前面(A=65,a=97),所以:
Apple
Banana
apple
banana
不区分大小写时会变成 Apple, apple, Banana, banana(按字母序交错)。需要哪种取决于用途:
- 文件名、代码标识符:通常区分大小写。
- 名单、标签:通常不区分,读起来更自然。
三、中文怎么排
三种常见规则:
| 规则 | 依据 | 特点 |
|---|---|---|
| 拼音 | 汉字转拼音后比较 | 符合日常习惯,最常用 |
| 笔画 | 笔画数 + 笔顺 | 字典、名册常用 |
| 编码 | Unicode 码点 | 实现简单,但顺序对人无意义 |
Unicode 码点排序下,常用汉字大致按部首/笔画分布,但不等于拼音序,直接排出来的名单看起来很乱。做中文名单排序要用支持 locale 的比较(如 Python 的 locale.strxfrm、JS 的 localeCompare('zh-CN'))。
四、排序 + 去重
两步的顺序会影响结果:
- 先排序再去重:得到有序的唯一列表,便于查找和对比。
- 先去重再排序:结果相同(集合意义),但如果去重是「保序」的,排序后就丢失了原始顺序。
如果原始顺序有意义(按时间、按优先级),应选择「保序去重」且不排序。
五、按某一列排序
处理 name,age,city 这样的数据时,需要指定「按第几列、什么类型」:
# 按第 2 列数值排序(-t 指定分隔符,-k 指定列)
sort -t',' -k2,2n data.csv
# 按第 1 列字符串排序
sort -t',' -k1,1 data.csv
-n 是数值,-r 倒序,-f 忽略大小写,-u 去重。注意 -k2,2n 里的 ,2 表示「只按第 2 列」,不写会从第 2 列一直比到行尾。
六、排序「不稳定」的错觉
同样的输入,两次排序结果不同,通常是因为:
- 比较键相同但整行不同,而排序算法不保证相同键的原始顺序(不稳定排序)。
- 数据里有不可见字符(空格、
\r、零宽字符),导致看起来一样但实际不同。 - 编码不同(全角/半角、大小写)。
处理:先清洗(trim、去 \r、统一全半角),再排序;需要稳定结果时,加上第二排序键(如整行)作为兜底。
七、几个实际场景
- 整理 IP 列表:按数值排序才能得到
1.2.3.4、1.2.3.10的正确顺序,按字符串会乱。要按段拆分后逐段比较。 - 整理日志时间:ISO 格式(
2026-11-03 10:00:00)可以直接按字符串排序,因为格式固定且高位在前——这也是推荐用 ISO 格式的原因。 - 整理标签:去空白 + 去重 + 按拼音排序,输出干净列表。
- 对比两份名单:各自排序后 diff,能快速看出增删。
八、工具
用 文本去重排序 可以按行去重、排序(支持忽略大小写、去首尾空白);对比排序前后的差异用 文本对比;核对行数变化用 字数统计。
小结
数字列用数值序,否则字典序会把 10 排在 9 前面;中文按拼音排要用 locale 比较;排序前去空白与不可见字符;需要原始顺序就别排序,用保序去重。