重命名
一个交互式、强调安全的文件批量重命名技能。它通过清晰的逐步对话引导用户完成重命名,
并且在真正改动任何文件之前强制先做一次独立完整备份。
底层重命名逻辑由 scripts/rename_engine.py(纯标准库,Python 3.8+,无需安装任何依赖)
实现;智能体的职责是把用户的自然语言意图翻译成规则(rules)+ 过滤(filters),
逐步确认,再调用引擎执行。
何时使用
- 用户连续输入“重命名”三个字(这是本技能的主要触发条件)。
- 用户提出批量改名诉求,例如“批量改名”“给这些文件加前缀/后缀”“把空格替换成下划线”
“按序号重排文件名”“把 IMG 开头的文件统一改名”。 - 任何需要对某个文件夹内的文件进行规范化、批量命名的任务。
核心原则(务必遵守)
- 分步交互,逐步确认:严格按照下面“四步流程”执行,每一步都先向用户提问并等待明确答复,
再进入下一步。不要一次抛出多个问题,也不要在用户未确认前执行任何会改动文件的动作。 - 执行前必须先完整备份:在真正重命名之前,必须调用引擎的
backup子命令,
把目标文件夹内的所有文件复制到独立的备份目录,并告知用户备份位置。 - 先预览后执行:生成重命名预览表,确认每个文件“旧名 → 新名”都正确,且用户明确同意后才执行。
- 绝不臆测路径:如果用户给的路径不存在或不是文件夹,明确指出并请其重新提供,不得自行替换。
- 个人/系统目录更谨慎:目标若是 Desktop / Downloads / Documents / Home 等个人目录,
先只列出将受影响的文件(扫描),再逐一确认,绝不使用rm或批量通配符删除。
四步流程
第一步:确认目标文件夹
向用户询问“需要对哪个文件夹内的文件进行重命名?请提供文件夹的完整路径。”
- 收到路径后,调用引擎扫描并展示文件清单,同时校验该路径是否为存在的文件夹:
python <skill>/scripts/rename_engine.py plan \
--dir "<目标文件夹路径>" \
--rules '[]' \
--plan-out "<目标文件夹路径>/.rename_plan.json"
- 若该路径不存在或不是文件夹,引擎会报错;此时明确告知用户,请其重新提供路径。
- 同时确认两点,可合并在一次提问里,但要等用户回答:
- 是否要递归处理子文件夹里的文件(默认只处理当前文件夹)。
- 是否需要过滤只处理某些类型的文件(如只看
.jpg、或只处理图片)。可在第二步一起明确。
展示文件清单后,进入第二步。
第二步:确认重命名规则
向用户询问希望执行何种重命名操作,并明确具体规则。可提供的选项(用自然语言解释,
让用户挑选或自行描述):
- 添加前缀:在文件名最前面加一段固定文字。
- 添加后缀:在文件名(扩展名之前)最后面加一段固定文字。
- 字符替换:把文件名中的某些字符替换成另一些(支持按字面替换,也支持正则)。
- 序号重排:按某种顺序(文件名/大小/修改时间)给文件依次编号,例如
file_001、file_002。 - 大小写 / 去空格等其它整理规则。
把用户的选择翻译成一条或多条 rules JSON 以及一个可选的 filters JSON。
完整的规则 schema(每个 op、字段、示例)见 references/rules.md。简明速查:
{"op":"prefix","value":"IMG_"}—— 前缀{"op":"suffix","value":"_edit"}—— 后缀(“后缀”作用于扩展名之前){"op":"replace","find":" ","replace":"_"}—— 字面替换{"op":"replace","find":"\\d+","replace":"X","regex":true}—— 正则替换("flags":"i"忽略大小写){"op":"case","mode":"lower"|"upper"}—— 大小写{"op":"trim"}—— 去除首尾空格{"op":"seq","template":"file_{n:03d}","start":1,"step":1}—— 序号重排({n}可带格式如:03d,{stem}为原名)- 过滤器示例:
{"ext":[".jpg",".png"]}、{"type":"image"}、{"glob":"*.jpg"}、{"regex":"^IMG","regex_target":"stem"}
示例:用户说“给图片加 IMG_ 前缀,再按序号重排成 photo_001.jpg”,对应规则为:
[
{"op":"prefix","value":"IMG_"},
{"op":"seq","template":"photo_{n:03d}","start":1}
]
规则明确后,进入第三步。
第三步:执行前完整备份
在真正重命名之前,必须先对目标文件夹内所有文件做一份独立完整备份:
python <skill>/scripts/rename_engine.py backup \
--dir "<目标文件夹路径>" \
--backup-dir "<任意独立备份目录>" # 例如 D:/rename_backup/20260825_204200
引擎会把目标文件夹内的所有文件复制到 --backup-dir 指定的独立目录,
并打印备份数量与位置。明确告诉用户备份目录路径,让用户知道原始文件已被安全留存。
> 注意:这一步的备份是“完整副本”,与执行阶段的重命名相互独立,
> 即使后续任何环节出问题,原始文件也都在备份目录里可恢复。
第四步:预览并确认执行
生成最终预览表,让用户看清“旧名 → 新名”:
python <skill>/scripts/rename_engine.py plan \
--dir "<目标文件夹路径>" \
--rules '<RULES_JSON>' \
--filters '<FILTERS_JSON>' \
--sort name \ # name | size | mtime | ctime
--recursive \ # 若第一步确认要递归
--plan-out "<目标文件夹路径>/.rename_plan.json"
把预览表呈现给用户,并提示:
- 标记为 rename 的文件将被改名;
- 标记为 skip(前后相同)的不会动;
- 标记为 CONFLICT(新名重复或已存在)的会被跳过,不会覆盖。
必须等待用户明确回复“确认/执行/可以”后,才运行执行命令(需带 --yes):
python <skill>/scripts/rename_engine.py run \
--plan "<目标文件夹路径>/.rename_plan.json" \
--yes
引擎会执行重命名并输出报告(重命名成功数 / 跳过数 / 失败数)。
收尾:汇报与撤销
- 向用户汇总执行结果,并再次给出第三步的备份目录路径,便于随时恢复。
- 提供一键撤销命令(把新名改回旧名):
python <skill>/scripts/rename_engine.py undo --manifest "<备份目录>/rename_manifest.json"
> 如果在第四步执行时使用了引擎自带的 --backup-dir 默认值,撤销清单位于
> <目标文件夹>/.batch-rename-backup/<时间戳>/rename_manifest.json;
> 若使用了第三步的独立备份目录,清单位于那个独立目录内。
安全与边界
- 预览优于执行:执行需要写好的 plan 文件 +
--yes双重确认。 - 先完整备份再改名:原始文件在独立备份目录留有副本,即使不撤销也能找回。
- 冲突保护:两个文件映射到同一新名,或新名在目录中已存在,会被标
CONFLICT并跳过,绝不覆盖。 - 重命名交换陷阱:若规则同时产生
A→B、B→C,第二阶段会报失败(目标已存在)而非覆盖;
必要时分两次执行。 - 个人/系统目录:Desktop / Downloads / Documents / Home 等先做只读扫描、列清单,
逐文件确认后再动,绝不用rm或批量通配符删除。 - 文件名净化:引擎会自动把
\ / : * ? " < > |替换为下划线,避免非法文件名。
故障排查
Refusing to run without --yes→ 调用run时漏了--yes;先与用户确认,再加上--yes。- 文件未变化 / 被 skip → 规则产出的名字与原名相同(例如空后缀),属正常,不是错误。
- 正则不匹配 → 确认规则里设置了
"regex":true,否则find会被当作字面字符串。 - 序号出现双扩展名(如
file_001jpg.jpg)→ 模板里不要写{ext},序号模板只描述“名(stem)”部分,
扩展名由引擎自动保留;如需保留原名用{stem}。
完整规则 schema 与更多示例见 references/rules.md。