linux uniq命令

Linux uniq命令用于报告或忽略文件中的重复行,通常与sort命令结合使用。

提示: uniq命令只能处理相邻的重复行,因此通常需要先使用sort命令对文件排序,以确保所有重复行相邻。

语法格式

uniq [选项] [输入文件 [输出文件]]

常用选项

选项 说明
-c 在每行前显示重复次数
-d 仅显示重复的行
-D 显示所有重复的行
-u 仅显示不重复的行
-i 忽略大小写
-f N 跳过前N个字段进行比较
-s N 跳过前N个字符进行比较
-w N 只比较前N个字符
--help 显示帮助信息
--version 显示版本信息

使用示例

示例1:基本去重

# 创建测试文件(注意重复行不相邻)
echo -e "apple\nbanana\napple\norange\nbanana\napple" > fruits.txt

# 直接使用uniq(无效,因为重复行不相邻)
uniq fruits.txt

# 先排序,再使用uniq
sort fruits.txt | uniq

# 输出:
# apple
# banana
# orange

示例2:显示重复次数

# 统计每行出现的次数
sort fruits.txt | uniq -c

# 输出:
#       3 apple
#       2 banana
#       1 orange

# 按次数排序(最常出现的在前)
sort fruits.txt | uniq -c | sort -nr

示例3:仅显示重复行

# 只显示有重复的行
sort fruits.txt | uniq -d

# 输出:
# apple
# banana

# 显示所有重复的行(每行都显示)
sort fruits.txt | uniq -D

# 输出:
# apple
# apple
# apple
# banana
# banana

示例4:仅显示不重复行

# 只显示没有重复的行
sort fruits.txt | uniq -u

# 输出:
# orange

示例5:忽略大小写

# 创建大小写混合的文件
echo -e "Apple\napple\nAPPLE\nBanana\nbanana" > mixed.txt

# 忽略大小写进行去重
sort mixed.txt | uniq -i

# 输出:
# Apple
# Banana

示例6:基于字段去重

# 创建以空格分隔的数据文件
echo -e "user1 john@example.com\nuser2 jane@example.com\nuser1 john@example.com\nuser3 bob@example.com" > users.txt

# 跳过第一个字段(用户名),基于第二个字段(邮箱)去重
sort users.txt | uniq -f 1

# 输出:
# user1 john@example.com
# user2 jane@example.com
# user3 bob@example.com

示例7:基于字符位置去重

# 创建测试文件
echo -e "12345\n12367\n12389\n12456\n12567" > numbers.txt

# 只比较前3个字符
sort numbers.txt | uniq -w 3

# 输出:
# 12345
# 12456
# 12567

# 跳过前2个字符进行比较
sort numbers.txt | uniq -s 2

# 输出:
# 12345

示例8:实际应用场景

# 统计日志文件中IP地址出现次数
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10

# 查找重复文件(基于MD5)
find . -type f -exec md5sum {} \; | sort | uniq -Dw32

# 检查配置文件中重复的设置
grep -v '^#' config.conf | grep -v '^$' | sort | uniq -d

# 统计单词频率
echo "apple banana apple cherry banana apple" | tr ' ' '\n' | sort | uniq -c

# 提取唯一的URL列表
awk -F'"' '{print $2}' access.log | sort | uniq

示例9:高级用法

# 使用字段和字符组合
echo -e "01 apple\n02 banana\n03 apple\n04 cherry" | sort -k2 | uniq -f1

# 输出基于第二个字段去重的结果

# 与awk结合,处理复杂格式
echo -e "A:10\nB:20\nA:30\nC:40" | awk -F: '{print $1}' | sort | uniq -c

# 处理CSV文件
cat data.csv | cut -d',' -f1 | sort | uniq -c
注意:
  • uniq命令默认只处理相邻的重复行,通常需要先使用sort命令
  • 如果指定了输出文件,结果将写入该文件,而不是标准输出
  • -f-s选项指定的字段和字符从1开始计数
  • 字段默认以空白字符(空格、制表符)分隔
  • 对于大文件,组合使用sort和uniq可能会消耗较多内存
  • -D选项在某些较旧的uniq版本中可能不可用

uniq工作流程

标准流程:
  1. 读取输入文件
  2. 比较当前行与上一行
  3. 根据选项决定输出
  4. 重复直到文件结束
典型管道组合:
# 最常见的组合
sort 输入文件 | uniq [选项]

# 带统计的排序去重
sort 文件 | uniq -c | sort -nr

# 提取唯一值并排序
cat 文件 | uniq | sort

性能优化技巧

  • 对大文件使用LC_ALL=C提高排序速度:LC_ALL=C sort file | uniq
  • 使用-T选项为sort指定临时目录
  • 对于已经部分排序的文件,可以考虑使用sort -m合并排序
  • 如果只需要检查是否有重复,可以使用uniq -d提前终止
  • 对于纯数字或简单文本,使用简单的比较选项提高速度
  • 考虑使用awkpython处理超大文件的去重

常见问题解决

问题:去重不彻底

原因: 重复行不相邻

解决: 先使用sort命令排序

sort file.txt | uniq
问题:统计不准确

原因: 大小写或空格差异

解决: 使用-i忽略大小写,或先规范化数据

tr 'A-Z' 'a-z' < file.txt | sort | uniq -c

uniq与其他命令组合

组合 功能 示例
sort | uniq 完全去重 sort file | uniq
sort | uniq -c 统计频率 sort file | uniq -c
sort | uniq -c | sort -nr 按频率排序 sort file | uniq -c | sort -nr
awk | sort | uniq 提取字段去重 awk '{print $1}' file | sort | uniq
grep | sort | uniq 过滤后去重 grep "error" log | sort | uniq

相关命令

  • sort - 排序命令,通常与uniq一起使用
  • awk - 文本处理工具,也可用于去重
  • cut - 列提取工具
  • comm - 比较两个已排序文件
  • join - 基于共同字段连接文件
  • wc - 统计行数、单词数、字符数