Linux下如何高效查找带多级子目录的文件夹内所有重复文件
高效查找多级目录下重复文件的实现方案
核心优化思路是把原始O(n²)的全量diff比对,替换为多层预筛选后仅对极小范围候选集做diff,性能可提升几个数量级,具体逻辑如下:
- 第一层预筛选:按文件大小分组。文件大小不同的文件执行diff不可能返回0,直接排除跨组比对的可能,绝大多数大小唯一的文件会在这一步直接排除出待比对池
- 第二层预筛选:对同大小组内的文件计算哈希值(可使用md5、sha256等),仅哈希值完全相同的文件才可能是重复文件,哈希计算速度远快于全文件diff
- 最终校验:仅对哈希值相同的文件执行diff确认,避免极小概率的哈希碰撞导致的误判,完全符合你对重复文件的定义要求
实现代码
#!/bin/bash # 替换为你的根目录路径 ROOT_DIR="/path/to/root/folder" # 生成所有文件的大小、哈希、路径映射表 find "$ROOT_DIR" -type f -print0 | while IFS= read -r -d '' file; do # Linux环境获取文件大小,macOS请替换为 stat -f "%z" "$file" size=$(stat -c "%s" "$file") # 计算md5哈希,也可替换为sha256sum md5=$(md5sum "$file" | awk '{print $1}') echo "$size $md5 $file" done | sort > /tmp/file_sig_list.tmp # 筛选出存在重复特征的文件组,组内两两diff确认 awk '{print $1" "$2}' /tmp/file_sig_list.tmp | uniq -d | while read -r sig; do files=($(grep "^$sig " /tmp/file_sig_list.tmp | awk '{print $3}')) file_count=${#files[@]} for ((i=0; i<file_count-1; i++)); do for ((j=i+1; j<file_count; j++)); do diff "${files[$i]}" "${files[$j]}" > /dev/null if [ $? -eq 0 ]; then echo "${files[$i]} MATCHES ${files[$j]}" fi done done done # 清理临时文件 rm -f /tmp/file_sig_list.tmp
可选优化
如果场景不需要100%规避哈希碰撞的极端情况,可以直接去掉最终diff步骤,相同哈希直接判定为重复,运行速度会更快。
内容的提问来源于stack exchange,提问作者I Z
相关产品推荐
相关产品推荐

