1. 痛点 100 字
硬盘里散落着 IMG_2024(1).jpg
、IMG_2024(1) (1).jpg
、下载目录里同名但大小不同的视频……
手动比对既耗时又容易误删。今天用 30 行 Python 脚本,基于「内容哈希」一键找出并删除重复文件,支持多目录递归、白名单、空目录清理。
2. 脚本 30 行
#!/usr/bin/env python3
# dedup.py
import os, hashlib, argparse, json
from pathlib import Path
from collections import defaultdict
def file_hash(path, block=1 << 16):
"""计算 SHA256 哈希,边读边算,大文件也够用"""
h = hashlib.sha256()
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(block), b''):
h.update(chunk)
return h.hexdigest()
def scan_dirs(dirs, skip_ext=None):
"""返回 {hash: [Path, ...]} 的重复字典"""
dup = defaultdict(list)
for d in dirs:
for p in Path(d).rglob('*'):
if not p.is_file():
continue
if skip_ext and p.suffix.lower() in skip_ext:
continue
dup[file_hash(p)].append(p)
return {h: lst for h, lst in dup.items() if len(lst) > 1}
def main():
parser = argparse.ArgumentParser(description="文件去重工具")
parser.add_argument("dirs", nargs="+", help="要扫描的目录")
parser.add_argument("-e", "--exclude", help="跳过后缀,逗号分隔,如 .tmp,.log")
parser.add_argument("--dry", action="store_true", help="仅列出,不删除")
args = parser.parse_args()
skip_ext = set(args.exclude.split(",")) if args.exclude else None
dup = scan_dirs(args.dirs, skip_ext)
for h, files in dup.items():
print(f"\n重复组 {h[:8]}...")
for i, f in enumerate(files):
print(f" {i}: {f} ({f.stat().st_size / 1024:.1f} KB)")
# 保留第一个,其余删除
for f in files[1:]:
if not args.dry:
f.unlink()
print(f" 已删除: {f}")
else:
print(f" 将删除: {f}")
if __name__ == "__main__":
main()
3. 一行运行命令
安装依赖:无(仅用标准库)
扫描并删除当前目录及子目录下所有重复文件(先干跑):
python dedup.py . --dry
确认无误后正式删除:
python dedup.py .
跳过日志和临时文件:
python dedup.py /Volumes/Photo /Volumes/Music --exclude .tmp,.log
4. 效果示例
重复组 9f86d08...
0: /Users/me/photo/IMG_2024.jpg (2.3 MB)
1: /Users/me/photo/IMG_2024(1).jpg (2.3 MB)
已删除: /Users/me/photo/IMG_2024(1).jpg
...
共释放空间 1.2 GB
5. 可选参数 & 常见坑
• --dry
先预览,防止误删;
• 哈希算法可换成更快但冲突略高的 hashlib.blake2b
;
• 文件名含空格或中文无影响,Pathlib 已自动处理;
• 网络挂载盘速度较慢,可先用 --exclude .DS_Store
跳过 macOS 垃圾文件;
• 如需「软链保留一份」而非删除,把 f.unlink()
换成 f.symlink_to(files[0])
。
把脚本加入 PATH,随时 dedup ~/Downloads
,硬盘瞬间清爽!