自动化:批量文件重命名
一、前言
今天来分享一款好玩的自动化脚:批量文件重命名
有时候呢,你的文件被下载下来文件名都是乱七八糟毫无规律,但是当时你下载的时候没办法重名或者你又不想另存为重新重命名。
比如:下载下来的照片每一个文件名字系统给你安排的都是系统自身的喜好
所以它来了,一次性完成。
二、效果

三、源码
这里有一个智能家居项目(毕设)可以看看(开源:码、论、PPT)
python
import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from pathlib import Path
class BatchRenameApp:
def __init__(self, root):
self.root = root
self.root.title(" 批量文件重命名工具 v1.0")
self.root.geometry("800x600")
# 变量初始化
self.folder_path = tk.StringVar()
self.prefix = tk.StringVar(value="")
self.suffix = tk.StringVar(value="")
self.start_num = tk.IntVar(value=1)
self.ext_filter = tk.StringVar(value="*")
self.dry_run = tk.BooleanVar(value=False)
self.file_list = []
# 创建UI组件
self.create_widgets()
def create_widgets(self):
# 顶部框架 - 文件夹选择和基本信息
top_frame = ttk.LabelFrame(self.root, text="文件夹设置", padding=(10, 5))
top_frame.pack(fill=tk.X, padx=10, pady=5)
ttk.Label(top_frame, text="目标文件夹:").grid(row=0, column=0, sticky=tk.W)
ttk.Entry(top_frame, textvariable=self.folder_path, width=50).grid(row=0, column=1, padx=5)
ttk.Button(top_frame, text="浏览...", command=self.browse_folder).grid(row=0, column=2)
# 中间框架 - 重命名规则设置
middle_frame = ttk.LabelFrame(self.root, text="重命名规则", padding=(10, 5))
middle_frame.pack(fill=tk.X, padx=10, pady=5)
ttk.Label(middle_frame, text="文件名前缀:").grid(row=0, column=0, sticky=tk.W)
ttk.Entry(middle_frame, textvariable=self.prefix).grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)
ttk.Label(middle_frame, text="文件名后缀:").grid(row=1, column=0, sticky=tk.W)
ttk.Entry(middle_frame, textvariable=self.suffix).grid(row=1, column=1, padx=5, pady=5, sticky=tk.W)
ttk.Label(middle_frame, text="起始编号:").grid(row=2, column=0, sticky=tk.W)
ttk.Spinbox(middle_frame, textvariable=self.start_num, from_=1, to=9999).grid(row=2, column=1, padx=5, pady=5,
sticky=tk.W)
ttk.Label(middle_frame, text="文件类型:").grid(row=3, column=0, sticky=tk.W)
ttk.Entry(middle_frame, textvariable=self.ext_filter).grid(row=3, column=1, padx=5, pady=5, sticky=tk.W)
ttk.Checkbutton(middle_frame, text="仅预览(不实际修改)", variable=self.dry_run).grid(row=4, column=0,
columnspan=2, pady=5)
# 底部框架 - 操作按钮和文件列表
bottom_frame = ttk.Frame(self.root)
bottom_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
button_frame = ttk.Frame(bottom_frame)
button_frame.pack(fill=tk.X, pady=5)
ttk.Button(button_frame, text="扫描文件", command=self.scan_files).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="预览重命名", command=self.preview_rename).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="执行重命名", command=self.execute_rename).pack(side=tk.LEFT, padx=5)
# 文件列表树状视图
self.tree = ttk.Treeview(bottom_frame, columns=("new_name", "status"), show="headings")
self.tree.heading("#0", text="原始文件名")
self.tree.heading("new_name", text="新文件名")
self.tree.heading("status", text="状态")
vsb = ttk.Scrollbar(bottom_frame, orient="vertical", command=self.tree.yview)
hsb = ttk.Scrollbar(bottom_frame, orient="horizontal", command=self.tree.xview)
self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
vsb.pack(side=tk.RIGHT, fill=tk.Y)
hsb.pack(side=tk.BOTTOM, fill=tk.X)
def browse_folder(self):
folder_selected = filedialog.askdirectory()
if folder_selected:
self.folder_path.set(folder_selected)
self.scan_files()
def scan_files(self):
folder = Path(self.folder_path.get())
if not folder.exists():
messagebox.showerror(" 错误", "文件夹不存在!")
return
ext = self.ext_filter.get().strip()
pattern = f"*.{ext}" if ext != "*" else "*"
try:
self.file_list = sorted([f for f in folder.glob(pattern) if f.is_file() and not f.name.startswith('.')])
self.update_file_list()
messagebox.showinfo(" 完成", f"找到 {len(self.file_list)} 个文件")
except Exception as e:
messagebox.showerror(" 错误", f"扫描文件时出错: {str(e)}")
def update_file_list(self):
self.tree.delete(*self.tree.get_children())
for i, file in enumerate(self.file_list, start=self.start_num.get()):
new_name = f"{self.prefix.get()}{i}{self.suffix.get()}{file.suffix}"
self.tree.insert("", tk.END, text=file.name, values=(new_name, "待处理"))
def preview_rename(self):
if not self.file_list:
messagebox.showwarning(" 警告", "请先扫描文件!")
return
self.dry_run.set(True)
self.update_file_list()
messagebox.showinfo(" 预览", "已生成重命名预览,请查看文件列表")
def execute_rename(self):
if not self.file_list:
messagebox.showwarning(" 警告", "请先扫描文件!")
return
if self.dry_run.get():
messagebox.showinfo(" 信息", "当前处于预览模式,不会实际修改文件")
return
if not messagebox.askyesno(" 确认", f"确定要重命名 {len(self.file_list)} 个文件吗?"):
return
success_count = 0
for i, file in enumerate(self.file_list, start=self.start_num.get()):
new_name = f"{self.prefix.get()}{i}{self.suffix.get()}{file.suffix}"
new_path = file.with_name(new_name)
try:
file.rename(new_path)
self.tree.item(self.tree.get_children()[i - self.start_num.get()],
values=(new_name, "成功"))
success_count += 1
except Exception as e:
self.tree.item(self.tree.get_children()[i - self.start_num.get()],
values=(new_name, f"失败: {str(e)}"))
messagebox.showinfo(" 完成", f"操作完成!\n成功: {success_count}\n失败: {len(self.file_list) - success_count}")
self.file_list = [] # 清空文件列表,防止重复操作
if __name__ == "__main__":
root = tk.Tk()
app = BatchRenameApp(root)
root.mainloop()