本文目录导读:

- 方案一:基础批量重命名(添加前缀/后缀)
- 方案二:序列号重命名
- 方案三:替换文件名中的特定文本
- 方案四:高级批量重命名(正则表达式)
- 方案五:基于文件元数据重命名(照片示例)
- 方案六:完整封装的批量重命名工具类
- 使用建议
我来为您介绍几种批量文件重命名的Python实现方案,包含不同的应用场景。
基础批量重命名(添加前缀/后缀)
import os
import glob
def batch_rename_add_prefix_suffix(folder_path, prefix='', suffix='', file_ext='*'):
"""
批量添加前缀或后缀
:param folder_path: 文件夹路径
:param prefix: 要添加的前缀
:param suffix: 要添加的后缀(不含扩展名)
:param file_ext: 文件扩展名,如'.txt','.jpg'
"""
# 获取所有匹配的文件
pattern = os.path.join(folder_path, f'*.{file_ext}' if file_ext != '*' else '*')
files = glob.glob(pattern)
for file_path in files:
# 分离文件名和扩展名
dir_name = os.path.dirname(file_path)
file_name, ext = os.path.splitext(os.path.basename(file_path))
# 构建新文件名
new_name = f"{prefix}{file_name}{suffix}{ext}"
new_path = os.path.join(dir_name, new_name)
# 执行重命名
os.rename(file_path, new_path)
print(f"重命名: {os.path.basename(file_path)} -> {new_name}")
# 使用示例
batch_rename_add_prefix_suffix('./my_files', prefix='2024_', suffix='_new', file_ext='txt')
序列号重命名
import os
def batch_rename_sequential(folder_path, base_name='file', start_num=1, digits=3, file_ext=None):
"""
批量重命名为序列号格式
:param folder_path: 文件夹路径
:param base_name: 基础文件名
:param start_num: 起始编号
:param digits: 编号位数
:param file_ext: 指定文件扩展名(可选)
"""
files = os.listdir(folder_path)
# 过滤文件(排除文件夹)
files = [f for f in files if os.path.isfile(os.path.join(folder_path, f))]
# 如果指定了扩展名,进一步过滤
if file_ext:
files = [f for f in files if f.endswith(file_ext)]
# 可选:按文件名排序
files.sort()
for i, old_name in enumerate(files):
_, ext = os.path.splitext(old_name)
new_name = f"{base_name}_{str(start_num + i).zfill(digits)}{ext}"
old_path = os.path.join(folder_path, old_name)
new_path = os.path.join(folder_path, new_name)
os.rename(old_path, new_path)
print(f"{old_name} -> {new_name}")
# 使用示例
batch_rename_sequential('./images', base_name='photo', start_num=1, digits=4, file_ext='.jpg')
替换文件名中的特定文本
import os
def batch_rename_replace_text(folder_path, old_text, new_text, file_ext=None):
"""
批量替换文件名中的文本
:param folder_path: 文件夹路径
:param old_text: 要替换的文本
:param new_text: 新文本
:param file_ext: 指定文件扩展名(可选)
"""
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
# 跳过文件夹
if not os.path.isfile(file_path):
continue
# 检查扩展名
if file_ext and not file_name.endswith(file_ext):
continue
# 执行替换
if old_text in file_name:
new_name = file_name.replace(old_text, new_text)
new_path = os.path.join(folder_path, new_name)
os.rename(file_path, new_path)
print(f"替换: {file_name} -> {new_name}")
# 使用示例
batch_rename_replace_text('./documents', old_text='_old', new_text='_new', file_ext='.pdf')
高级批量重命名(正则表达式)
import os
import re
def batch_rename_regex(folder_path, pattern, replacement, file_ext=None):
"""
使用正则表达式批量重命名
:param folder_path: 文件夹路径
:param pattern: 正则表达式模式
:param replacement: 替换字符串
:param file_ext: 指定文件扩展名(可选)
"""
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
if not os.path.isfile(file_path):
continue
if file_ext and not file_name.endswith(file_ext):
continue
# 使用正则表达式替换
new_name = re.sub(pattern, replacement, file_name)
if new_name != file_name:
new_path = os.path.join(folder_path, new_name)
# 检查新文件名是否已存在
if not os.path.exists(new_path):
os.rename(file_path, new_path)
print(f"正则重命名: {file_name} -> {new_name}")
else:
print(f"跳过: {file_name} -> {new_name} (文件已存在)")
# 使用示例:移除文件名中的数字
batch_rename_regex('./data', pattern=r'\d+', replacement='', file_ext='.txt')
# 使用示例:将下划线替换为连字符
batch_rename_regex('./files', pattern=r'_', replacement='-')
基于文件元数据重命名(照片示例)
import os
import datetime
from PIL import Image
from PIL.ExifTags import TAGS
def get_photo_date(file_path):
"""获取照片的拍摄日期"""
try:
image = Image.open(file_path)
exifdata = image.getexif()
for tag_id, value in exifdata.items():
tag = TAGS.get(tag_id, tag_id)
if tag == "DateTimeOriginal":
return datetime.datetime.strptime(value, "%Y:%m:%d %H:%M:%S")
except:
# 如果无法获取EXIF信息,使用文件修改时间
return datetime.datetime.fromtimestamp(os.path.getmtime(file_path))
return None
def batch_rename_photos_by_date(folder_path):
"""
使用照片拍摄日期重命名
"""
photo_extensions = ['.jpg', '.jpeg', '.png', '.raw']
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
if not os.path.isfile(file_path):
continue
ext = os.path.splitext(file_name)[1].lower()
if ext not in photo_extensions:
continue
# 获取拍摄日期
photo_date = get_photo_date(file_path)
if photo_date:
new_name = f"{photo_date.strftime('%Y%m%d_%H%M%S')}{ext}"
new_path = os.path.join(folder_path, new_name)
os.rename(file_path, new_path)
print(f"照片重命名: {file_name} -> {new_name}")
# 使用前需要安装:pip install Pillow
# batch_rename_photos_by_date('./photos')
完整封装的批量重命名工具类
import os
import shutil
from typing import List, Callable
class FileRenamer:
"""批量文件重命名工具类"""
def __init__(self, folder_path: str):
self.folder_path = folder_path
self.backup_folder = None
def get_files(self, pattern: str = None) -> List[str]:
"""获取文件列表"""
files = []
for f in os.listdir(self.folder_path):
file_path = os.path.join(self.folder_path, f)
if os.path.isfile(file_path):
if pattern is None or f.endswith(pattern):
files.append(f)
return sorted(files)
def create_backup(self) -> str:
"""创建备份文件夹"""
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
self.backup_folder = f"{self.folder_path}_backup_{timestamp}"
shutil.copytree(self.folder_path, self.backup_folder)
print(f"备份创建成功: {self.backup_folder}")
return self.backup_folder
def rename(self, rename_func: Callable[[str], str], preview: bool = True):
"""
执行重命名操作
:param rename_func: 重命名函数,接收原文件名,返回新文件名
:param preview: 是否预览(不实际执行)
"""
files = self.get_files()
operations = []
for file_name in files:
new_name = rename_func(file_name)
if new_name and new_name != file_name:
operations.append((file_name, new_name))
if preview:
print("=== 预览重命名操作 ===")
for old, new in operations:
print(f"{old} -> {new}")
print(f"共 {len(operations)} 个文件将被重命名")
else:
# 创建备份
self.create_backup()
# 执行重命名
for old_name, new_name in operations:
old_path = os.path.join(self.folder_path, old_name)
new_path = os.path.join(self.folder_path, new_name)
if not os.path.exists(new_path):
os.rename(old_path, new_path)
print(f"重命名: {old_name} -> {new_name}")
else:
print(f"跳过: {new_name} 已存在")
# 使用示例
def main():
renamer = FileRenamer('./my_files')
# 定义重命名规则
def add_date_prefix(filename):
from datetime import datetime
date_str = datetime.now().strftime("%Y%m%d")
return f"{date_str}_{filename}"
# 预览
renamer.rename(add_date_prefix, preview=True)
# 实际执行
# renamer.rename(add_date_prefix, preview=False)
if __name__ == "__main__":
main()
使用建议
- 先备份:在批量重命名前,建议先备份重要文件
- 先预览:使用
preview=True预览效果后再执行 - 测试小范围:先用少量文件测试
- 正则表达式:复杂的文本替换可使用正则表达式
这些方法涵盖了大部分批量重命名需求,您可以根据具体场景选择合适的方案。