首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >用 WorkBuddy 写 Python 脚本,半小时搞定几万份文件批量去重

用 WorkBuddy 写 Python 脚本,半小时搞定几万份文件批量去重

原创
作者头像
用户12813287
发布于 2026-10-12 01:27:29
发布于 2026-10-12 01:27:29
120
举报

适用人群:手里有大量重复文件的人——爬下来的素材、重复备份、导出稿……手动找重复是不可能的。 我本地一个素材库有 7 万多份文件,光靠眼睛根本没法收拾。后来发现这活儿根本不用自己写代码:把需求描述清楚丢给 WorkBuddy,它几秒出脚本,我跑一下、看清单、分批删。整套流程半小时跑通,还能识别"内容一样但标点/编码不同"的变体重复。下面完整复现。


一、痛点:为什么手动去重不现实

  • 量太大:7 万份文件,两两比对是天文数字,肉眼+资源管理器排序也救不了。
  • 重复很"狡猾":很多不是字节级一模一样,而是全角半角、空白、中英文标点不同造成的"近似重复",普通哈希去重会漏掉。
  • 删错成本高:直接 rm 万一删了唯一正本,没法回退。

核心需求就三个:能跑、能识别变体、不直接删。


二、思路:你只描述需求,WorkBuddy 出脚本

不要自己从零写。打开 WorkBuddy,把下面这段提示词贴进去(直接复制改目录即可):

代码语言:javascript
复制
帮我写一个 Python 脚本,遍历指定目录下的所有 .txt 文件,按内容做去重。
要求:
1) 先按文件内容 MD5 精确去重;
2) 再做一层"近似去重":把全角/半角、空白、中英文标点统一归一化后再哈希,
   识别格式/标点变体造成的重复;
3) 输出一份 CSV,每行 = 重复组哈希 + 保留路径 + 待删除路径;
4) 不要直接删除文件,只生成清单供人工核对;
5) 遇到编码错误跳过,不要崩。
只用 Python 标准库。

跑出来就是下面这段可直接用的脚本。


三、完整脚本(已实测可运行)

代码语言:javascript
复制
import hashlib, os, re, csv, unicodedata

def normalize(text):
    """归一化:NFKC 统一全角半角 -> 转小写 -> 去所有空白 -> 去常见中英文标点"""
    text = unicodedata.normalize("NFKC", text)
    text = text.lower()
    text = re.sub(r"\s+", "", text)
    text = re.sub(r"[,。!?、;:""''()【】《》—…·.,!?:;\"'()\[\]{}<>/\\|]", "", text)
    return text

def read_text(path):
    # 先按 utf-8,失败再按 gbk;再不行忽略错误,保证不崩
    for enc in ("utf-8", "gbk"):
        try:
            with open(path, encoding=enc) as f:
                return f.read()
        except (UnicodeDecodeError, OSError):
            continue
    with open(path, encoding="utf-8", errors="ignore") as f:
        return f.read()

def content_keys(path):
    txt = read_text(path)
    exact = hashlib.md5(txt.encode("utf-8", "ignore")).hexdigest()
    near = hashlib.md5(normalize(txt).encode("utf-8", "ignore")).hexdigest()
    return exact, near

def find_dupes(root, ext=".txt"):
    exact_groups, near_groups = {}, {}
    for dirpath, _, files in os.walk(root):
        for name in files:
            if not name.lower().endswith(ext):
                continue
            p = os.path.join(dirpath, name)
            try:
                e, n = content_keys(p)
            except Exception:
                continue
            exact_groups.setdefault(e, []).append(p)
            near_groups.setdefault(n, []).append(p)
    return exact_groups, near_groups

def write_report(root):
    exact, near = find_dupes(root)
    rows = []
    # 精确重复
    for h, paths in exact.items():
        if len(paths) > 1:
            keep, *dels = sorted(paths, key=lambda x: (len(x), x))
            for d in dels:
                rows.append([h, "exact", keep, d])
    # 近似重复(同一精确组内不再重复报)
    seen_exact = {frozenset(v) for v in exact.values() if len(v) > 1}
    for h, paths in near.items():
        if len(paths) > 1 and frozenset(paths) not in seen_exact:
            keep, *dels = sorted(paths, key=lambda x: (len(x), x))
            for d in dels:
                rows.append([h, "near", keep, d])
    out = os.path.join(root, "dup_report.csv")
    with open(out, "w", newline="", encoding="utf-8-sig") as f:
        w = csv.writer(f)
        w.writerow(["hash", "type", "keep", "delete"])
        w.writerows(rows)
    print(f"生成清单:{out}")
    print(f"精确重复待删 {sum(len(v)-1 for v in exact.values() if len(v)>1)} 个")
    print(f"近似重复待删 {len(rows) - sum(len(v)-1 for v in exact.values() if len(v)>1)} 个")

if __name__ == "__main__":
    write_report(r"D:\小说库")   # 改成你自己的目录

把 r"D:\小说库" 换成你的目录,保存为 dedup.py,命令行跑 python dedup.py 即可。


四、拿到清单后怎么安全删(关键,别跳过)

脚本只生成 dup_report.csv,不直接删,这是有意的安全设计。删除前做三步:

  1. 先整体备份目录(或至少确认有回收站可恢复)。
  2. 人工扫一眼 CSV 的 delete 列,确认都是真的重复、不是唯一正本。
  3. 分批走回收站删除,不要一次性 rm。Windows 上可以这样把待删文件移进回收站:
代码语言:javascript
复制
import shutil, csv, os

def to_trash(csv_path, batch=200):
    with open(csv_path, encoding="utf-8-sig") as f:
        for i, row in enumerate(csv.DictReader(f)):
            if i >= batch:
                print("已处理一批,确认无误后再跑下一批")
                break
            p = row["delete"]
            if os.path.exists(p):
                shutil.move(p, os.path.join(os.environ["RecycleBin"], os.path.basename(p)))
                # 没有回收站变量就改用 shutil.move 到备份文件夹
    print("本批完成")

# to_trash("D:\\小说库\\dup_report.csv")

删完重新跑一次脚本(迭代删除 + 重新扫描),直到 dup_report.csv 不再新增——重复就收敛干净了。


五、省时账

方式

7 万文件去重耗时

能否识别变体

安全性

手动比对/排序

不可能完成

否

易误删

只做精确哈希

半天写+跑,但漏变体

否

中

WorkBuddy 出脚本 + 近似归一化(本文)

半小时

是

高(先清单后删)

WorkBuddy 省掉的是"从零写+调试"的时间;脚本里的归一化逻辑是真正解决"变体重复"的关键,也是手写最容易漏的一步。


六、小结

批量去重这类脏活,正确姿势是:用 WorkBuddy 把需求翻译成脚本,你跑脚本、看清单、分批删。记住三条铁律——只生成清单不直接删、先备份再动手、删完重新扫描迭代收敛。把对的事交给对的工具,几万份文件也能半小时理清楚。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、痛点:为什么手动去重不现实
  • 二、思路:你只描述需求,WorkBuddy 出脚本
  • 三、完整脚本(已实测可运行)
  • 四、拿到清单后怎么安全删(关键,别跳过)
  • 五、省时账
  • 六、小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档