sort、uniq 与计数去重¶
sort 对行进行排序,uniq 只比较相邻行。要对分散在文件各处的重复值计数,通常先排序再使用 uniq。
sort 基础¶
| 选项 | 作用 |
|---|---|
-n |
数值排序 |
-r |
逆序 |
-u |
排序并去重 |
-f |
忽略大小写 |
-t |
指定字段分隔符 |
-k |
指定排序键 |
-h |
按 K/M/G 等人类可读单位排序,非 POSIX |
-V |
版本号自然排序,GNU/BSD 支持情况需确认 |
按字段排序¶
-k2,2n 表示只按第 2 字段数值排序;写成 -k2n 可能把第 2 字段到行尾都当作键,结果与预期不同。
uniq¶
| 选项 | 作用 |
|---|---|
-c |
在每行前显示相邻重复次数 |
-d |
只显示重复值 |
-u |
只显示只出现一次的值 |
-i |
比较时忽略大小写 |
错误示例:
如果相同内容不相邻,它不会被去重。正确组合:
Top N¶
理解每一阶段:
Locale 的影响¶
字符排序受 LC_COLLATE 影响。同一脚本在不同语言环境可能得到不同顺序;处理机器数据和稳定结果时可指定:
C locale 通常更快且按字节顺序,但中文等自然语言排序不符合人类习惯。不要把改变 locale 当成无条件优化。
大文件¶
sort 会使用内存和临时文件。大日志排序前先按时间/字段过滤,确认临时目录空间:
-S、-T 的细节可能因实现不同。根分区较小时,默认临时目录也可能被大排序撑满。
集合操作¶
sort -u file1 file2 # 并集
sort file1 file2 | uniq -d # 交集
sort file1 file1 file2 | uniq -u # file2 相对 file1 的差异式用法需理解数据集合
更清晰的两个已排序文件比较可使用 comm:
LC_ALL=C sort -u file1 > file1.sorted
LC_ALL=C sort -u file2 > file2.sorted
comm -12 file1.sorted file2.sorted # 交集
comm -23 file1.sorted file2.sorted # 只在 file1
官方参考:GNU Coreutils sort/uniq。