uniq只能去重相邻重复行,无法全文去重;真正删所有重复需先sort再uniq或用sort -u,保序去重则必须用awk'!seen[$0]++'。

uniq 不能直接去重全文重复行,它只处理连续重复的相邻行;想真正删掉所有重复内容,必须先 sort 再 uniq,或改用 awk '!seen[$0]++' 保持原序。
为什么直接 uniq file.txt 常常没效果?
常见错误现象:文件里明明有重复行(比如第3行和第12行一模一样),但运行后输出和输入完全一致。
-
uniq不扫描全文,也不建哈希表——它只是从头到尾扫一遍,只合并紧挨着的重复行 - 如果重复行被其他内容隔开(即不相邻),
uniq完全无视 - 未排序的文件中,相同内容大概率分散在不同位置,所以“去重”等于白跑
sort | uniq 和 sort -u 有什么实际区别?
两者功能等价,但使用场景和可扩展性不同:
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
-
sort file.txt | uniq:显式两步,适合中间加处理,比如sort file.txt | awk '{print $1}' | uniq -
sort -u file.txt:一步到位,语义清晰、性能略优,推荐日常全局去重首选 - 注意:
sort -u输出是排序后的结果;如果你需要保留原始顺序,这两个都不可用
怎么在不去乱顺序的前提下删除全文重复行?
当顺序敏感(如日志时间线、配置项顺序、脚本执行序列),sort 和 uniq 都失效,必须靠带内存状态的工具:
- 最常用的是:
awk '!seen[$0]++' file.txt——逐行读取,用关联数组记录是否见过该行 - 若要忽略首尾空格影响,得先清理:
awk '{gsub(/^[ \t]+|[ \t]+$/, ""); if (!seen[$0]++) print}' file.txt - 大文件慎用:所有唯一行会暂存内存,几 GB 的日志可能触发 OOM
-
perl -ne 'print unless $seen{$_}++'行为一致,适合已有 Perl 环境的场景
按字段或忽略大小写去重,uniq 能不能搞定?
uniq 提供了 -f、-s、-i、-w 等选项,但能力有限且容易误判:
- 忽略大小写可用:
sort -f file.txt | uniq -i(-f排序时忽略,-i去重时也忽略) - 按第一列去重:
sort -k1,1 file.txt | uniq -w N不可靠,因为-w只截前 N 字符,不是按字段切分 - 真正按列操作请用
awk:awk '!seen[$1]++' file.txt(空格分隔)或awk -F'\t' '!seen[$3]++' file.txt(制表符分隔第3列)
最容易被忽略的其实是需求判断:你到底要“删掉连续重复”还是“删掉全文重复”。前者用 uniq 本身即可,后者绕不开排序或哈希;别急着敲命令,先看一眼数据分布和顺序要求。

















