uniq 命令详解#

uniq 是 Linux 系统中用于去除或报告重复行的命令。它通常与 sort 命令配合使用,因为 uniq 只能去除相邻的重复行。

入门#

基本用法#

# 去除相邻的重复行
uniq filename.txt

# 从标准输入处理
cat file.txt | uniq
command | uniq

常用选项#

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

基本示例#

# 去除重复行
uniq names.txt

# 显示重复次数
uniq -c names.txt

# 只显示重复的行
uniq -d names.txt

# 只显示不重复的行
uniq -u names.txt

# 忽略大小写
uniq -i names.txt

中级#

字段和字符处理#

# 跳过前2个字段
uniq -f2 filename.txt

# 跳过前5个字符
uniq -s5 filename.txt

# 只比较前10个字符
uniq -w10 filename.txt

# 组合使用
uniq -f1 -s2 -w10 filename.txt

高级选项#

# 显示所有重复的行
uniq -D filename.txt

# 显示重复行的重复次数
uniq -c filename.txt

# 只显示出现一次的行
uniq -u filename.txt

# 只显示重复的行(每组一个)
uniq -d filename.txt

与 sort 配合使用#

# 先排序再去重
sort filename.txt | uniq

# 排序并统计重复次数
sort filename.txt | uniq -c

# 按重复次数排序
sort filename.txt | uniq -c | sort -rn

# 查找重复最多的行
sort filename.txt | uniq -c | sort -rn | head -n 10

输出控制#

# 将结果写入文件
sort filename.txt | uniq > output.txt

# 追加到文件
sort filename.txt | uniq >> output.txt

# 同时显示和保存
sort filename.txt | uniq | tee output.txt

高级#

复杂数据处理#

# 统计词频
cat text.txt | tr ' ' '\n' | sort | uniq -c | sort -rn

# 统计IP访问次数
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -n 10

# 查找重复文件
find . -type f -exec md5sum {} \; | sort | uniq -d -w32

# 统计错误日志
grep "ERROR" log.txt | sort | uniq -c | sort -rn

高级过滤#

# 查找重复超过N次的行
sort filename.txt | uniq -c | awk '$1 > N'

# 查找只出现一次的行
sort filename.txt | uniq -u

# 查找出现N次的行
sort filename.txt | uniq -c | awk '$1 == N'

# 按特定字段去重
sort -k2 filename.txt | uniq -f1

脚本集成#

# 文件去重脚本
#!/bin/bash
INPUT="$1"
OUTPUT="$2"

if [ -z "$OUTPUT" ]; then
    OUTPUT="${INPUT}.uniq"
fi

sort "$INPUT" | uniq > "$OUTPUT"
echo "Deduplicated file saved to: $OUTPUT"

# 统计重复行脚本
#!/bin/bash
FILE="$1"

echo "Duplicate lines in $FILE:"
sort "$FILE" | uniq -d

# 词频统计脚本
#!/bin/bash
FILE="$1"

echo "Word frequency in $FILE:"
cat "$FILE" | tr ' ' '\n' | sort | uniq -c | sort -rn

性能优化#

# 处理大文件
sort largefile.txt | uniq > output.txt

# 使用临时文件
sort -T /tmp largefile.txt | uniq > output.txt

# 并行处理
sort --parallel=4 largefile.txt | uniq > output.txt

大师#

高级分析#

# 日志分析
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -n 20

# 用户行为分析
awk '{print $1, $7}' access.log | sort | uniq -c | sort -rn

# 错误分析
grep "ERROR" app.log | awk '{print $5}' | sort | uniq -c | sort -rn

# 访问路径分析
awk '{print $7}' access.log | sort | uniq -c | sort -rn

数据清洗#

# 清洗CSV文件
sort -t, -k1 data.csv | uniq -f0 > cleaned.csv

# 去除重复的配置项
sort config.conf | uniq > cleaned.conf

# 清洗日志文件
sort log.txt | uniq -c | awk '$1 > 1' > duplicates.txt

复杂示例#

# 查找重复的邮箱地址
grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' emails.txt | sort | uniq -d

# 统计每个用户的操作次数
awk '{print $1}' operations.log | sort | uniq -c | sort -rn

# 查找重复的代码行
grep -v '^\s*$' code.py | sort | uniq -d

# 分析访问模式
awk '{print $1, $4}' access.log | sort | uniq -c | sort -rn | head -n 50

与其他命令组合#

# 查找重复文件
find . -type f -exec md5sum {} \; | sort | uniq -d -w32 | cut -d' ' -f3-

# 统计文件类型
find . -type f -name "*.txt" | wc -l
find . -type f -name "*.txt" -exec basename {} \; | sort | uniq -c

# 分析进程
ps aux | awk '{print $11}' | sort | uniq -c | sort -rn

# 分析网络连接
netstat -an | awk '{print $5}' | sort | uniq -c | sort -rn

无敌#

高级技巧#

# 多条件去重
sort -k1,1 -k2,2 data.txt | uniq -f1

# 按特定模式去重
grep "pattern" file.txt | sort | uniq -d

# 使用正则表达式去重
grep -E 'regex' file.txt | sort | uniq -d

# 智能去重(忽略空格和大小写)
tr -s ' ' < file.txt | tr '[:upper:]' '[:lower:]' | sort | uniq -c

大文件处理#

# 分块处理大文件
split -l 1000000 largefile.txt chunk_
for chunk in chunk_*; do
    sort "$chunk" | uniq -c > "$chunk.uniq"
done
cat chunk_*.uniq | sort -rn > final_result.txt

# 使用外部排序
sort --buffer-size=1G largefile.txt | uniq > output.txt

# 并行处理
find . -name "*.log" -exec sh -c 'sort "$1" | uniq -c' _ {} \; | sort -rn

自动化工作流#

# 自动化日志分析
#!/bin/bash
LOG_DIR="/var/log"
REPORT_DIR="./reports"
mkdir -p "$REPORT_DIR"

DATE=$(date +%Y-%m-%d)
find "$LOG_DIR" -name "*$DATE*" -type f | while read log; do
    filename=$(basename "$log")
    awk '{print $1}' "$log" | sort | uniq -c | sort -rn > "$REPORT_DIR/$filename.stats"
done

# 自动化数据清洗
#!/bin/bash
INPUT_DIR="./input"
OUTPUT_DIR="./output"
mkdir -p "$OUTPUT_DIR"

for file in "$INPUT_DIR"/*.csv; do
    filename=$(basename "$file")
    sort -t, -k1 "$file" | uniq -f0 > "$OUTPUT_DIR/$filename"
done

# 自动化重复检测
#!/bin/bash
DIRECTORY="$1"

echo "Checking for duplicate files in $DIRECTORY"
find "$DIRECTORY" -type f -exec md5sum {} \; | sort | uniq -d -w32 | while read hash file; do
    echo "Duplicate found: $file"
done

性能调优#

# 监控性能
time sort largefile.txt | uniq -c

# 使用 strace 分析
strace -c sort largefile.txt | uniq

# 使用 valgrind 分析内存
valgrind --tool=massif sort largefile.txt | uniq

# 优化处理
sort --parallel=$(nproc) -S $(free -m | awk '/Mem:/ {print $2}')M largefile.txt | uniq

高级应用场景#

# 数据库数据去重
mysql -u user -p database -e "SELECT * FROM table" | sort | uniq -f1

# 系统监控分析
vmstat 1 100 | awk '{print $1}' | sort | uniq -c

# 网络流量分析
tcpdump -i eth0 -n | awk '{print $3}' | sort | uniq -c | sort -rn

# 用户活动分析
last | awk '{print $1}' | sort | uniq -c | sort -rn

最佳实践#

1. 使用场景#

  • 数据去重和清洗
  • 日志分析和统计
  • 重复数据检测
  • 词频统计和分析

2. 性能优化#

  • 先使用 sort 排序,再使用 uniq
  • 对于大文件,使用合适的缓冲区大小
  • 使用并行处理提高速度
  • 合理使用临时文件

3. 数据处理#

  • 结合 awk 进行复杂的数据提取
  • 使用 grep 过滤特定模式
  • 与 sort 配合进行多条件排序
  • 使用 cut 提取特定字段

4. 脚本集成#

  • 在脚本中使用管道组合命令
  • 处理错误和异常情况
  • 使用变量和参数化脚本
  • 添加日志和调试信息

5. 学习路径#

  • 先掌握基本去重功能
  • 学习统计和过滤选项
  • 掌握与 sort 的配合使用
  • 学习高级分析和脚本集成
  • 最后学习性能优化和自动化

常见问题#

Q: uniq 为什么不能去除所有重复行?#

A: uniq 只能去除相邻的重复行,需要先使用 sort 排序才能去除所有重复行。

Q: 如何统计重复次数?#

A: 使用 uniq -c 选项在每行前显示重复次数。

Q: 如何只显示重复的行?#

A: 使用 uniq -d 选项只显示重复的行。

Q: 如何忽略大小写去重?#

A: 使用 uniq -i 选项忽略大小写。

Q: 如何按特定字段去重?#

A: 使用 uniq -f 选项跳过前N个字段,或先使用 sort 按字段排序。

相关命令#

  • sort - 排序文本行
  • cut - 提取字段
  • awk - 文本处理
  • grep - 搜索文本
  • comm - 比较排序文件