文件整理工具箱
成品公式:用户丢一个乱目录 + 一句话 → 拿到整理好的目录结构(不是教程、不是贴代码)。典型用户:手机/相机相册一堆 IMG_xxxx、下载文件夹堆满各种文件、多个目录里散落着同一个文件的多个副本——要改名、要归档、要查重。
纯 Python 标准库(hashlib / os / shutil / re / pathlib)实现,无第三方依赖;中文文件名/路径全程友好。
功能
| 子命令 | 用途 | 典型场景 |
|---|---|---|
rename |
批量重命名 | IMG_2031.jpg 一串 → 照片_001.jpg;把文件里统一的前缀/后缀批量改掉 |
organize |
按类型或日期归档到子目录 | 下载文件夹自动拆成 图片/文档/视频/音频/压缩包/其他;按 YYYY-MM 分月归类 |
dedup |
按文件内容查找重复文件 | 相册里同一张图存了好几份;输出重复组清单(可导出 CSV),可选删除 |
三个子命令都支持 --dry-run:只打印"将要做什么",不产生任何实际变更。dedup 默认只报告,删除必须显式加 --delete。
工作流程
- 问清目标 + 确认目录:先让用户说清 ① 要整理哪个目录(拿到绝对路径)② 想达到什么结果(改名 / 归档 / 查重)③ 是否有特殊规则(按时间排序?按哪种方式归档?)。
- 危险操作先预览:
rename/organize会改动文件、dedup --delete会删文件——一律先加--dry-run跑一遍,把预览结果念给用户确认(尤其是organize会移动文件、rename可能撞名)。 - 选子命令、拼命令:用绝对路径;
--pattern的占位符是{n}(序号,可用{n:03d}补零)、{name}(原名不含扩展名)、{ext}(扩展名不含点)。拿不准规则就先给出选项问用户,不要替用户拍板排序/命名。 - 运行并核对摘要:检查打印的"已处理 / 跳过 / 冲突"数字是否合理;有
[冲突]说明撞名被跳过,要向用户解释原因并给修正建议。 - 交付结果:给出目录的绝对路径 + 一句话结果(如"3 张图已改名为 照片_001~003.jpg");
dedup若生成 CSV 报告,给出报告绝对路径。
命令参考
脚本路径:scripts/file_organizer.py(可用 python3 直接调用,见 --help)。
rename —— 批量重命名
python3 scripts/file_organizer.py rename <目录> [选项]
--pattern "模板":命名模板,支持{n}(序号)、{name}(原名)、{ext}(扩展名)。
例:--pattern "照片_{n:03d}.jpg"→照片_001.jpg、照片_002.jpg…--find 旧文本 --replace 新文本:查找替换(默认纯文本)。--regex:把--find当正则表达式。例--find "_v\d+" --replace "" --regex去掉版本号。--sort name|mtime|size:重命名前的排序依据(默认name)。相册序号改名务必用--sort mtime,否则顺序可能不是拍摄时间。--start N:{n}起始值(默认 1)。--recursive/--include-hidden/--dry-run。
> --pattern 与 --find 只能二选一。
organize —— 按类型或日期归档
python3 scripts/file_organizer.py organize <目录> [选项]
--by type(默认):按扩展名归入图片/ 文档/ 视频/ 音频/ 压缩包/ 其他子目录。--by date:按文件修改时间归入YYYY-MM子目录。--copy:复制而非移动(默认为移动)。--recursive/--include-hidden/--dry-run。
dedup —— 重复文件查找
python3 scripts/file_organizer.py dedup <目录> [选项]
--min-size 字节数:忽略小于该大小的文件(如--min-size 1024)。--report dup.csv:把重复组清单导出为 CSV(UTF-8-BOM,Excel 直接打开不乱码)。--delete:删除重复文件(每组保留第一个)。默认不加,只报告。 非交互环境须再配--yes。--no-recursive:不递归(dedup 默认递归扫描子目录)。--dry-run:配合--delete时只预览将删哪些文件。--include-hidden。
示例对话
例 1|相册序号改名
> 用户:我手机导出来一堆照片,文件名乱得很,帮我按拍摄时间改成 照片_001.jpg 这种。
> 助手:先预览(不会改任何东西):
> python3 scripts/file_organizer.py rename /home/u/相册 --pattern "照片_{n:03d}.jpg" --sort mtime --dry-run
> 确认顺序没错后执行:去掉 --dry-run。→ 交付:"43 张照片已按拍摄时间改名为 照片_001~043.jpg。"
例 2|下载文件夹归档
> 用户:下载文件夹太乱了,帮我按类型分一下。
> 助手:python3 scripts/file_organizer.py organize /home/u/下载 --by type --dry-run
> 用户确认后执行 → 生成 图片/ 文档/ 视频/ 音频/ 压缩包/ 其他/ 六个子目录。
例 3|查重复文件
> 用户:我这个相册里好像有重复的图,帮我看看。
> 助手:python3 scripts/file_organizer.py dedup /home/u/相册 --min-size 10240 --report dup.csv
> → 报告"发现 3 组重复,共 5 个冗余文件,浪费 12.4 MB",并导出 dup.csv(只报告不删)。
> 用户要删时再跑 --delete(脚本会二次确认)。
运行环境
- 脚本:
scripts/file_organizer.py(相对技能根目录) - Python:3.9+,脚本只用标准库,不需要 pip 安装任何包
- 外部命令:无
注意事项
- ⚠️ 危险操作先
--dry-run:rename和organize会真实改动文件,organize默认是移动(不是复制),dedup --delete会永久删除。执行前一律先预览,并把预览结果给用户过目。 - ⚠️ rename 撞名会跳过:若目标文件名已存在,或两个文件会改成同名,脚本打印
[冲突]并跳过该文件(不覆盖、不报错中断)。想看为什么没改全,看[冲突]行。 - ⚠️ rename 不做两步改名:
--pattern是原地改名,若新名字恰好等于目录里另一个"也会被改名"的文件现有名字,会判为冲突跳过。遇到这种"整体平移"顺序,建议先改成临时名再改回来(或分批处理)。 - ⚠️ organize --by date 依据文件修改时间(mtime),不是拍摄/创建时间;解压、拷贝可能改动 mtime,结果可能和预期不一致,先
--dry-run看归档结果。 dedup按文件内容(SHA256)判重,内容完全相同才算重复;同名不同内容不算。先按大小粗筛再算哈希,大目录也快。- 默认跳过隐藏文件(
.开头),需要时加--include-hidden;默认不递归(organize/rename),dedup默认递归。 - 删除类操作请提醒用户:重要文件先备份;
--delete不可撤销。