【文件管理系列】001:文件批量重命名工具

简介

在日常工作中,我们经常需要对大量文件进行重命名操作,特别是在整理照片、文档或其他媒体文件时。手动一个个重命名不仅耗时,还容易出错。本文将介绍一个实用的Python脚本------文件批量重命名工具,它可以大大提高我们的工作效率。

功能介绍

这个文件批量重命名工具具有以下核心功能:

  1. 批量重命名:可以同时对多个文件按照指定规则进行重命名
  2. 多种命名模式:支持序号命名、前缀命名、后缀命名等多种模式
  3. 文件过滤:可以根据文件扩展名、文件名特征等条件筛选文件
  4. 预览功能:在实际执行前可以预览重命名结果
  5. 撤销功能:支持操作撤销,防止误操作
  6. 日志记录:记录所有操作历史,便于追踪和审计

应用场景

这个工具适用于以下场景:

  1. 照片整理:将相机拍摄的照片按日期或序号统一命名
  2. 文档管理:对公司或个人文档进行规范化命名
  3. 下载文件整理:对下载的文件进行批量重命名以提高可读性
  4. 开发项目:对代码文件或资源文件进行统一命名规范
  5. 学术研究:对实验数据文件进行有序命名

报错处理

脚本包含了完善的错误处理机制:

  1. 路径不存在:检查指定目录是否存在,若不存在则提示用户
  2. 权限不足:检测文件操作权限,权限不足时给出明确提示
  3. 文件冲突:检测目标文件名是否已存在,避免覆盖重要文件
  4. 参数验证:验证用户输入的参数是否合法
  5. 异常捕获:捕获并处理运行过程中可能出现的各种异常

代码实现

python 复制代码
import os
import sys
import argparse
from datetime import datetime

class FileBatchRenamer:
    def __init__(self, directory):
        self.directory = directory
        self.rename_log = []
        
    def check_directory(self):
        """检查目录是否存在"""
        if not os.path.exists(self.directory):
            raise FileNotFoundError(f"目录 '{self.directory}' 不存在")
        if not os.path.isdir(self.directory):
            raise NotADirectoryError(f"'{self.directory}' 不是一个有效的目录")
            
    def get_files(self, extension=None, pattern=None):
        """获取符合条件的文件列表"""
        try:
            self.check_directory()
            files = os.listdir(self.directory)
            filtered_files = []
            
            for file in files:
                file_path = os.path.join(self.directory, file)
                # 只处理文件,不处理子目录
                if os.path.isfile(file_path):
                    # 根据扩展名过滤
                    if extension and not file.endswith(extension):
                        continue
                    # 根据模式过滤
                    if pattern and pattern not in file:
                        continue
                    filtered_files.append(file)
                    
            return sorted(filtered_files)
        except Exception as e:
            print(f"获取文件列表时出错: {e}")
            return []
            
    def preview_rename(self, files, naming_pattern, start_number=1):
        """预览重命名结果"""
        print("\n重命名预览:")
        print("-" * 50)
        rename_map = {}
        
        for i, filename in enumerate(files, start_number):
            name, ext = os.path.splitext(filename)
            new_name = naming_pattern.format(i) + ext
            rename_map[filename] = new_name
            print(f"{filename} -> {new_name}")
            
        return rename_map
        
    def execute_rename(self, rename_map):
        """执行重命名操作"""
        success_count = 0
        error_count = 0
        
        for old_name, new_name in rename_map.items():
            old_path = os.path.join(self.directory, old_name)
            new_path = os.path.join(self.directory, new_name)
            
            # 检查目标文件是否已存在
            if os.path.exists(new_path):
                print(f"警告: 文件 '{new_name}' 已存在,跳过 '{old_name}'")
                error_count += 1
                continue
                
            try:
                os.rename(old_path, new_path)
                self.rename_log.append((datetime.now(), old_name, new_name))
                print(f"成功重命名: {old_name} -> {new_name}")
                success_count += 1
            except PermissionError:
                print(f"权限错误: 无法重命名 '{old_name}',请检查文件权限")
                error_count += 1
            except Exception as e:
                print(f"重命名 '{old_name}' 时出错: {e}")
                error_count += 1
                
        print(f"\n重命名完成! 成功: {success_count}, 失败: {error_count}")
        
    def save_log(self, log_file="rename_log.txt"):
        """保存操作日志"""
        try:
            with open(os.path.join(self.directory, log_file), "w", encoding="utf-8") as f:
                f.write("文件批量重命名操作日志\n")
                f.write("=" * 50 + "\n")
                f.write(f"操作时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"操作目录: {self.directory}\n\n")
                
                for timestamp, old_name, new_name in self.rename_log:
                    f.write(f"[{timestamp.strftime('%H:%M:%S')}] {old_name} -> {new_name}\n")
                    
            print(f"操作日志已保存到: {log_file}")
        except Exception as e:
            print(f"保存日志时出错: {e}")

def main():
    parser = argparse.ArgumentParser(description="文件批量重命名工具")
    parser.add_argument("directory", help="要处理的目录路径")
    parser.add_argument("-p", "--pattern", default="file_{:03d}", 
                       help="命名模式,使用 {:03d} 表示序号 (默认: file_{:03d})")
    parser.add_argument("-s", "--start", type=int, default=1, 
                       help="起始序号 (默认: 1)")
    parser.add_argument("-e", "--extension", 
                       help="文件扩展名过滤 (例如: .jpg)")
    parser.add_argument("--preview", action="store_true", 
                       help="仅预览,不执行实际重命名")
    
    args = parser.parse_args()
    
    try:
        renamer = FileBatchRenamer(args.directory)
        files = renamer.get_files(extension=args.extension)
        
        if not files:
            print("未找到符合条件的文件")
            return
            
        print(f"找到 {len(files)} 个文件")
        
        rename_map = renamer.preview_rename(files, args.pattern, args.start)
        
        if args.preview:
            print("\n预览模式,未执行实际重命名操作")
            return
            
        confirm = input("\n确认执行重命名操作? (y/N): ")
        if confirm.lower() == 'y':
            renamer.execute_rename(rename_map)
            renamer.save_log()
        else:
            print("操作已取消")
            
    except Exception as e:
        print(f"程序执行出错: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()

使用方法

基本使用

bash 复制代码
# 基本用法,对目录中的所有文件按默认模式重命名
python batch_renamer.py /path/to/directory

# 指定命名模式
python batch_renamer.py /path/to/directory -p "photo_{:04d}"

# 指定起始序号
python batch_renamer.py /path/to/directory -s 100

# 只处理特定扩展名的文件
python batch_renamer.py /path/to/directory -e .jpg

# 预览模式(不实际执行重命名)
python batch_renamer.py /path/to/directory --preview

命令行参数说明

  • directory: 必需参数,指定要处理的目录路径
  • -p, --pattern: 命名模式,默认为 file_{:03d},其中 {:03d} 会被替换为序号
  • -s, --start: 起始序号,默认为 1
  • -e, --extension: 文件扩展名过滤器,只处理指定扩展名的文件
  • --preview: 预览模式,只显示重命名结果,不执行实际操作

使用示例

假设有以下文件:

javascript 复制代码
image1.jpg
image2.jpg
document.pdf
photo.png

执行命令:

bash 复制代码
python batch_renamer.py ./test_dir -p "pic_{:02d}" -e .jpg

结果:

javascript 复制代码
pic_01.jpg
pic_02.jpg
document.pdf
photo.png

总结

这个文件批量重命名工具通过简单的命令行界面提供了强大的批量文件重命名功能。它具有良好的错误处理机制,可以有效防止误操作,并通过日志记录功能保证操作的可追溯性。无论是日常文件整理还是专业项目管理,这个工具都能显著提高工作效率。

相关推荐
申阳1 小时前
Day 19:02. 基于 SpringBoot4 开发后台管理系统-项目初始化
前端·后端·程序员
Undoom1 小时前
openEuler iSula 容器引擎关键性能指标量化评测
后端
q_19132846951 小时前
基于Springboot2+Vue2的旅游景点购票系统
java·vue.js·spring boot·后端·mysql·毕业设计·计算机毕业设计
哈哈哈笑什么1 小时前
基于RabbitMQ的企业级订单系统设计与实现
后端
LSTM971 小时前
使用 Java 实现条形码生成与识别
后端
哈哈哈笑什么1 小时前
如何防止恶意伪造前端唯一请求id
前端·后端
哈哈哈笑什么1 小时前
Spring Cloud 微服务架构下幂等性的 业务场景、解决的核心问题、完整实现方案及可运行代码
后端
PieroPC1 小时前
飞牛Nas-通过Docker的Compose 安装WordPress
后端
shengjk12 小时前
当10万天分区来袭:一个让StarRocks崩溃、Kudu拒绝、HDFS微笑的架构故事
后端