uniq只能去重相邻重复行,因不扫描全文且无哈希机制;全文去重要先sort再uniq或用awk;需保序则用awk'!seen[$0]++';按列/忽略大小写等复杂需求awk更可靠。

uniq 本身不能全文去重,它只删相邻重复行;想真正去掉所有重复,必须先 sort,再 uniq,或者换用 awk。
为什么直接 uniq file.txt 经常没效果?
常见错误现象:uniq 输出和原文件一模一样,哪怕肉眼可见有重复行。
-
uniq不扫描全文,也不建哈希表,它只是从头到尾扫一遍,只把紧挨着的重复行压成一行 - 如果重复行分散在第 3 行和第 17 行,
uniq完全无视 - 未排序的文件中,相同内容大概率不相邻,
uniq就等于白跑
全文去重必须先 sort,但要注意输出顺序
sort file.txt | uniq 和 sort -u file.txt 功能等价,但后者更常用、语义更清晰。
-
sort -u是一步到位,性能略优,且避免管道中间出错 - 两者都输出排序后的结果——如果你需要保持原始顺序,这条路走不通
- 若需保留首次出现位置(比如日志去重、配置项去重),必须用
awk '!seen[$0]++'
按字段或忽略大小写去重,uniq 能力有限
uniq -f N 或 uniq -i 可以跳字段或忽略大小写,但逻辑简单粗暴,容易误判。
-
uniq -w N只比前 N 字符,不是按列切分,对制表符/空格分隔的字段不可靠 - 按第一列去重,应写
awk '!seen[$1]++' file.txt;按第三列(制表符分隔)则用awk -F'\t' '!seen[$3]++' file.txt - 忽略大小写去重,
sort -f file.txt | uniq -i可行,但awk '{line=tolower($0)} !seen[line]++'更可控
大文件或特殊格式要小心内存和换行符
awk '!seen[$0]++' 这类内存型方案,看似万能,但有隐性代价。
- 所有唯一行都缓存在内存里,几 GB 的日志可能触发 OOM
-
$0包含换行符,若行首/行尾有空格干扰判断,得先gsub(/^[ \t]+|[ \t]+$/, "") - 二进制数据或含
\0的输入,uniq默认不支持,需加-z,而awk需配合RS="\0"
最常被忽略的其实是需求本身:你要的是“去相邻重复”还是“去全文重复”?前者 uniq 自己就能干,后者绕不开排序或哈希——别急着敲命令,先想清楚你到底想留下哪一行。











