Skip to content

文件批量重命名工具

约 2211 字大约 7 分钟

Python文件处理批量操作正则表达式

2024-10-16

一个强大的Python脚本,支持使用正则表达式批量重命名文件,提供演示模式确保安全操作。

功能说明

这是一个命令行文件批量重命名工具,主要特性:

  • 🔍 正则表达式支持 - 强大的模式匹配和替换功能
  • 🛡️ 演示模式 - 预览重命名结果,不实际修改文件
  • 📁 批量处理 - 一次性处理整个目录的文件
  • 错误处理 - 捕获并显示重命名过程中的错误
  • 📊 详细输出 - 显示每个文件的重命名操作

使用场景

  • 📝 统一文件扩展名(.txt → .md)
  • 🔄 批量替换文件名中的字符
  • 🗂️ 规范化文件命名格式
  • 🔢 添加或删除文件名前缀/后缀
  • 🧹 清理文件名中的特殊字符

环境要求

Python版本

  • Python 3.6+

依赖库

无需额外依赖,仅使用Python标准库:

  • os - 文件系统操作
  • re - 正则表达式
  • argparse - 命令行参数解析
  • pathlib - 路径处理

安装方法

方式一:直接下载

# 下载脚本
wget https://cnb.cool/merma/ScriptsHub/-/raw/main/scripts/python/utils/batch_rename.py

# 添加执行权限
chmod +x batch_rename.py

方式二:使用 curl

# 下载脚本
curl -O https://cnb.cool/merma/ScriptsHub/-/raw/main/scripts/python/utils/batch_rename.py

# 添加执行权限
chmod +x batch_rename.py

方式三:克隆仓库

git clone https://cnb.cool/merma/ScriptsHub.git
cd ScriptsHub/scripts/python/utils
chmod +x batch_rename.py

使用方法

基本语法

python batch_rename.py <> <匹配模> <替换字符> [选项]

参数说明

  • directory - 目标目录路径(必需)
  • pattern - 正则表达式匹配模式(必需)
  • replacement - 替换字符串(必需)
  • -d, --dry-run - 演示模式,不实际重命名文件(可选)
  • -v, --version - 显示版本信息(可选)

使用示例

示例 1: 修改文件扩展名

# 将所有 .txt 文件改为 .md
python batch_rename.py /path/to/dir "\.txt$" ".md"

效果:

document.txt -> document.md
readme.txt -> readme.md
notes.txt -> notes.md

示例 2: 替换文件名前缀

# 将 old 开头的文件名改为 new 开头
python batch_rename.py /path/to/dir "^old" "new"

效果:

old_file.txt -> new_file.txt
old_data.csv -> new_data.csv

示例 3: 删除文件名中的空格

# 将空格替换为下划线(先用演示模式测试)
python batch_rename.py /path/to/dir "\s+" "_" --dry-run

效果:

my file.txt -> my_file.txt
test data.csv -> test_data.csv

示例 4: 添加前缀

# 给所有文件添加 backup_ 前缀
python batch_rename.py /path/to/dir "^" "backup_"

效果:

file.txt -> backup_file.txt
data.csv -> backup_data.csv

示例 5: 删除特定字符

# 删除文件名中的数字
python batch_rename.py /path/to/dir "\d+" ""

效果:

file123.txt -> file.txt
data2023.csv -> data.csv

示例 6: 日期格式转换

# 将日期格式从 YYYY-MM-DD 改为 YYYYMMDD
python batch_rename.py /path/to/dir "(\d{4})-(\d{2})-(\d{2})" "\1\2\3"

效果:

report-2024-10-16.pdf -> report-20241016.pdf
data-2024-01-01.xlsx -> data-20240101.xlsx

演示模式

强烈建议先使用演示模式!

演示模式(--dry-run)会显示将要进行的重命名操作,但不会实际修改文件,用于:

  1. 预览重命名结果
  2. 检查正则表达式是否正确
  3. 避免误操作
# 演示模式示例
python batch_rename.py /path/to/dir "\.txt$" ".md" --dry-run

输出示例:

扫描目录: /path/to/dir
匹配模式: \.txt$
替换为: .md
模式: 演示模式
--------------------------------------------------
file1.txt -> file1.md
file2.txt -> file2.md
notes.txt -> notes.md
--------------------------------------------------
将会重命名 3 个文件

脚本源码

点击展开查看完整源码
#!/usr/bin/env python3
"""
文件批量重命名工具
批量重命名指定目录下的文件,支持正则表达式替换
"""

import os
import re
import argparse
from pathlib import Path

__version__ = "1.0.0"
__author__ = "ScriptsHub"


def rename_files(directory, pattern, replacement, dry_run=False):
    """
    批量重命名文件

    Args:
        directory: 目标目录
        pattern: 正则表达式模式
        replacement: 替换字符串
        dry_run: 是否为演示模式(不实际重命名)

    Returns:
        成功重命名的文件数量
    """
    count = 0
    path = Path(directory)

    if not path.exists():
        print(f"错误: 目录 '{directory}' 不存在")
        return 0

    print(f"扫描目录: {directory}")
    print(f"匹配模式: {pattern}")
    print(f"替换为: {replacement}")
    print(f"模式: {'演示模式' if dry_run else '执行模式'}")
    print("-" * 50)

    for file_path in path.iterdir():
        if file_path.is_file():
            old_name = file_path.name
            new_name = re.sub(pattern, replacement, old_name)

            if old_name != new_name:
                new_path = file_path.parent / new_name
                print(f"{old_name} -> {new_name}")

                if not dry_run:
                    try:
                        file_path.rename(new_path)
                        count += 1
                    except Exception as e:
                        print(f"  错误: {e}")
                else:
                    count += 1

    print("-" * 50)
    print(f"{'将会' if dry_run else ''}重命名 {count} 个文件")
    return count


def main():
    parser = argparse.ArgumentParser(
        description="批量重命名文件工具",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  %(prog)s /path/to/dir "\.txt$" ".md"           # 将 .txt 改为 .md
  %(prog)s /path/to/dir "^old" "new"             # 将 old 开头改为 new
  %(prog)s /path/to/dir "\\s+" "_" --dry-run     # 将空格替换为下划线(演示)
        """
    )

    parser.add_argument('directory', help='目标目录路径')
    parser.add_argument('pattern', help='正则表达式匹配模式')
    parser.add_argument('replacement', help='替换字符串')
    parser.add_argument('-d', '--dry-run', action='store_true',
                       help='演示模式,不实际重命名文件')
    parser.add_argument('-v', '--version', action='version',
                       version=f'%(prog)s {__version__}')

    args = parser.parse_args()

    # 执行重命名
    rename_files(args.directory, args.pattern, args.replacement, args.dry_run)


if __name__ == '__main__':
    main()

在 CNB 查看: batch_rename.py

代码解析

核心函数

def rename_files(directory, pattern, replacement, dry_run=False):
    path = Path(directory)

    # 遍历目录中的文件
    for file_path in path.iterdir():
        if file_path.is_file():
            old_name = file_path.name
            # 使用正则表达式替换
            new_name = re.sub(pattern, replacement, old_name)

            if old_name != new_name:
                # 执行重命名(或仅显示)
                if not dry_run:
                    file_path.rename(new_path)

关键技术点

  1. 正则表达式替换

    • re.sub(pattern, replacement, string) 进行模式匹配和替换
    • 支持捕获组 () 和反向引用 \1, \2
  2. 路径处理

    • 使用 pathlib.Path 进行跨平台路径操作
    • iterdir() 遍历目录内容
    • is_file() 判断是否为文件
  3. 命令行参数

    • argparse 解析命令行参数
    • action='store_true' 处理布尔选项
  4. 错误处理

    • try-except 捕获重命名异常
    • 显示错误信息但继续处理其他文件

正则表达式参考

常用模式

模式说明示例
^匹配开头^old 匹配以 old 开头
$匹配结尾\.txt$ 匹配以 .txt 结尾
.匹配任意字符file.txt 匹配 file+任意字符+txt
\d匹配数字\d+ 匹配一个或多个数字
\s匹配空白字符\s+ 匹配一个或多个空格
\w匹配字母数字下划线\w+ 匹配单词
*匹配0次或多次a* 匹配0个或多个a
+匹配1次或多次a+ 匹配1个或多个a
?匹配0次或1次a? 匹配0个或1个a
[]字符集[abc] 匹配a或b或c
()捕获组(\d{4}) 捕获4位数字

转义字符

需要匹配特殊字符时,使用反斜杠转义:

  • \. 匹配点号
  • \( 匹配左括号
  • \[ 匹配左方括号

注意事项

重要提示

  1. 先使用演示模式 - 避免误操作导致文件名错误
  2. 备份重要文件 - 重命名前建议备份
  3. 检查正则表达式 - 确保匹配模式正确
  4. 避免文件名冲突 - 确保重命名后的文件名不会重复

最佳实践

  • 使用 --dry-run 预览结果
  • 从小范围测试开始
  • 注意正则表达式的转义
  • 确保有足够的权限

常见问题

Q: 如何撤销重命名操作?

A: 本工具不支持撤销。建议:

  1. 先使用 --dry-run 演示模式
  2. 重命名前备份文件
  3. 记录重命名操作,手动恢复

Q: 可以递归处理子目录吗?

A: 当前版本仅处理指定目录的文件,不包括子目录。如需递归,可以修改脚本使用 rglob('*')walk()

Q: 如何处理文件名冲突?

A: 脚本会尝试重命名,如果目标文件名已存在,会抛出错误。建议设计不会产生冲突的重命名规则

Q: 正则表达式怎么写?

A: 参考上方"正则表达式参考"部分,或使用在线正则测试工具(如 regex101.com)先测试

Q: Windows 下如何使用?

A:

# 直接运行
python batch_rename.py C:\path\to\dir "\.txt$" ".md"

# 注意路径分隔符,或使用正斜杠
python batch_rename.py C:/path/to/dir "\.txt$" ".md"

实际应用案例

案例 1: 清理下载文件名

# 删除文件名中的 "副本" 字样
python batch_rename.py ~/Downloads "副本\d*" "" --dry-run

案例 2: 统一命名格式

# 将 IMG_20241016.jpg 改为 20241016-img.jpg
python batch_rename.py /photos "IMG_(\d{8})" "\1-img" --dry-run

案例 3: 批量添加编号

结合其他工具可以实现更复杂的功能,或修改脚本添加计数器功能。

扩展建议

可以基于此脚本扩展的功能:

  1. 递归处理 - 支持子目录
  2. 文件过滤 - 按扩展名或大小过滤
  3. 撤销功能 - 记录重命名历史
  4. GUI界面 - 使用tkinter创建图形界面
  5. 批量编号 - 自动添加序号

更新日志

v1.0.0 (2024-10-16)

  • ✨ 初始版本发布
  • 🔍 支持正则表达式匹配和替换
  • 🛡️ 添加演示模式
  • ✅ 基本错误处理

相关资源

许可证

MIT License


提示: 批量重命名是高风险操作,务必先使用 --dry-run 模式预览结果!