批量重命名并保留扩展名脚本

wen 实用脚本 2
#!/usr/bin/env python3
"""
批量重命名文件并保留原始扩展名。
用法:
    python rename_keep_ext.py <目录路径> <旧文本> <新文本> [--dry-run]
示例:
    将当前目录下所有文件名中的 "photo" 替换为 "image":
        python rename_keep_ext.py . photo image
    预览替换效果(不实际执行):
        python rename_keep_ext.py . photo image --dry-run
"""
import os
import sys
import argparse
def parse_arguments():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(
        description="批量重命名文件,仅修改文件名主体部分,保留原始扩展名。"
    )
    parser.add_argument(
        "directory",
        help="要处理的目录路径"
    )
    parser.add_argument(
        "old_text",
        help="要被替换的旧文本(区分大小写)"
    )
    parser.add_argument(
        "new_text",
        help="替换后的新文本"
    )
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="预览模式:只显示将要发生的操作,不实际执行重命名"
    )
    return parser.parse_args()
def batch_rename(directory, old_text, new_text, dry_run=False):
    """
    批量重命名目录中的文件。
    规则:
    - 只修改文件名的主干部分(不含扩展名)。
    - 如果替换后的文件名与现有文件冲突,则跳过该文件并输出警告。
    - 如果文件名中不包含 old_text,则跳过。
    """
    if not os.path.isdir(directory):
        print(f"错误:目录 '{directory}' 不存在或不是一个有效的目录。", file=sys.stderr)
        sys.exit(1)
    renamed_count = 0
    skipped_count = 0
    # 获取目录下所有文件(不包括子目录)
    entries = os.listdir(directory)
    files = [f for f in entries if os.path.isfile(os.path.join(directory, f))]
    if not files:
        print("目录中没有找到任何文件。")
        return
    print(f"在目录 '{directory}' 中查找包含 '{old_text}' 的文件...\n")
    for filename in files:
        # 分离文件名主干和扩展名
        name_part, ext = os.path.splitext(filename)
        # 如果主干中不包含旧文本,跳过
        if old_text not in name_part:
            continue
        # 执行替换(区分大小写)
        new_name_part = name_part.replace(old_text, new_text)
        new_filename = new_name_part + ext  # 保留原始扩展名
        # 如果新文件名没有变化,跳过(理论上不会发生,因为 old_text 在 name_part 中)
        if new_filename == filename:
            continue
        old_path = os.path.join(directory, filename)
        new_path = os.path.join(directory, new_filename)
        # 检查目标文件是否已存在(避免覆盖)
        if os.path.exists(new_path):
            print(f"⚠ 跳过:目标文件已存在 -> {new_filename} (源文件: {filename})")
            skipped_count += 1
            continue
        if dry_run:
            print(f"[预览] 将重命名: '{filename}' -> '{new_filename}'")
        else:
            try:
                os.rename(old_path, new_path)
                print(f"✔ 已重命名: '{filename}' -> '{new_filename}'")
                renamed_count += 1
            except OSError as e:
                print(f"✖ 重命名失败: {filename} -> {new_filename},错误: {e}", file=sys.stderr)
                skipped_count += 1
    print(f"\n操作完成。")
    print(f"  成功重命名: {renamed_count} 个文件")
    if skipped_count > 0:
        print(f"  跳过: {skipped_count} 个文件(冲突或错误)")
def main():
    args = parse_arguments()
    batch_rename(
        directory=args.directory,
        old_text=args.old_text,
        new_text=args.new_text,
        dry_run=args.dry_run
    )
if __name__ == "__main__":
    main()

使用说明

基本用法

将脚本保存为 rename_keep_ext.py,然后在终端运行:

批量重命名并保留扩展名脚本

python rename_keep_ext.py <目录路径> <旧文本> <新文本>

示例:将 /home/user/photos 目录下所有文件名中的 2024_ 替换为 2025_

python rename_keep_ext.py /home/user/photos 2024_ 2025_

预览模式(安全测试)

添加 --dry-run 参数可以只显示将要进行的重命名操作,而不实际修改文件:

python rename_keep_ext.py /home/user/photos 2024_ 2025_ --dry-run

功能特点

  • 保留扩展名:只修改文件名的主干部分(如 document.txt 中的 document
  • 区分大小写Photophoto 被视为不同字符串
  • 冲突检测:如果新文件名已存在,会自动跳过并提示
  • 详细输出:显示每个文件的重命名结果或跳过原因

常见场景

场景 命令示例
替换日期前缀 python rename_keep_ext.py . "2024_" "2025_"
修改项目名称 python rename_keep_ext.py ./docs "draft" "final"
清理文件名 python rename_keep_ext.py . " - Copy" ""
批量添加后缀 注意:此脚本不支持直接添加,需配合其他方法

如果需要更复杂的模式匹配(如正则表达式),可以扩展脚本或使用专门的工具(如 rename 命令或 sed)。

抱歉,评论功能暂时关闭!