自动化:批量文件重命名

news2025/5/19 13:11:01

自动化:批量文件重命名

1、前言
2、效果图
3、源码

一、前言

今天来分享一款好玩的自动化脚:批量文件重命名
有时候呢,你的文件被下载下来文件名都是乱七八糟毫无规律,但是当时你下载的时候没办法重名或者你又不想另存为重新重命名。
比如:下载下来的照片每一个文件名字系统给你安排的都是系统自身的喜好
在这里插入图片描述

所以它来了,一次性完成。

二、效果

在这里插入图片描述

三、源码

这里有一个智能家居项目(毕设)可以看看(开源:码、论、PPT)

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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习!FastAPI

目录 FastAPI简介快速开始安装FastApiFastAPI CLI自动化文档 Reqeust路径参数Enum 类用于路径参数路径参数和数值校验 查询参数查询参数和字符串校验 请求体多个请求体参数嵌入单个请求体参数 CookieHeader表单文件直接使用请求 ResponseResponse Model多个关联模型 响应状态码…

【第三十六周】LoRA 微调方法

LoRA 摘要Abstract文章信息引言方法LoRA的原理LoRA在Transformer中的应用补充其他细节 实验与分析LoRA的使用论文实验结果分析 总结 摘要 本篇博客介绍了LoRA(Low-Rank Adaptation),这是一种面向大规模预训练语言模型的参数高效微调方法&…

Redis 数据类型与操作完全指南

Redis 是一个开源的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。与传统的关系型数据库不同,Redis 提供了丰富的数据类型和灵活的操作方式,这使得它能够高效地解决各种不同场景下的数据存储和处理问题。本文将全面介绍 R…

Digi XBee XR 系列介绍

Digi 延续了 20 多年来亚 GHz 射频模块的传统,推出了 Digi XBee XR 系列远距离模块,包括 Digi XBee XR 900 - 已通过多个地区的预先认证 - 以及 Digi XBee XR 868 - 已通过欧洲地区应用的预先认证。 这些先进的射频模块专为远距离抗干扰无线通信而设计。…

【方法论】金字塔原理概述:写作逻辑的底层架构与实践法则

文章目录 一、为何采用金字塔结构:对抗认知局限的思维框架1、 梳理逻辑,抽象归纳2、自上而下,结论居首3、 结论先行之必要 三、金字塔结构1、纵向逻辑:上层思想必须是下层思想的概括提炼2、横向逻辑:每组思想需属于同一…

BERT 核心技术全解析:Transformer 双向编码与掩码语言建模的底层逻辑

一、引言:从 BERT 到生成式 AI 的进化之路 科学的突破从来不是孤立的奇迹,而是人类知识长河中无数基石的累积。 当我们惊叹于 ChatGPT、Google Bard 等大型语言模型(LLM)在生成式 AI 领域的惊人表现时,不能不回溯到 20…

【OpenCV基础 1】几何变换、形态学处理、阈值分割、区域提取和脱敏处理

目录 一、图像几何变化 1、对图片进行放大、缩小、水平放大和垂直放大 2、旋转、缩放、控制画布大小 二、图像形态学处理 1、梯度运算 2、闭运算 3、礼帽运算 4、黑帽运算 三、图像阈值分割 1、二值化处理 2、反二值化处理 3、截断阈值处理 4、超阈值零处理 5、低…

CSS- 4.4 固定定位(fixed) 咖啡售卖官网实例

本系列可作为前端学习系列的笔记,代码的运行环境是在HBuilder中,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 HTML系列文章 已经收录在前端专栏,有需要的宝宝们可以点击前端专栏查看! 点…

得力标签打印机系统集成方案的技术应用与场景实践

一、方案背景与技术特性 在物联网设备管理场景中,标签打印的自动化与效率提升成为企业数字化升级的重要需求。得力标签打印机驱动及系统集成方案,通过技术接口开发与硬件协同,为设备标识管理提供 轻量化对接能力。以下从技术适配性与功能设计…

【通用智能体】Playwright:跨浏览器自动化工具

Playwright:跨浏览器自动化工具 一、Playwright 是什么?二、应用场景及案例场景 1:端到端(E2E)测试场景 2:UI 自动化(表单批量提交)场景 3:页面截图与 PDF 生成场景 4&am…

精准掌控张力动态,重构卷对卷工艺设计

一、MapleSim Web Handling Library仿真和虚拟调试解决方案 在柔性材料加工领域,卷对卷(Roll-to-Roll)工艺的效率与质量直接决定了产品竞争力。如何在高动态生产场景中实现张力稳定、减少断裂风险、优化加工速度,是行业长期面临的…

永磁同步电机公式总结【一】——反电动势、磁链、转矩公式;三项、两项电压方程;坐标表换方程

一、PMSM 电机参数介绍 1.1 转子极数 转子极数 (Rotor Poles) :三相交流电机每组线圈都会产生 N、S 磁极,每个电机每相含有的永磁体磁极个数就是极数。由于磁极是成对出现的,所以电机有 2、4、6、8……极 (偶数)。 未知参数的电机&#xff…

STL - stack 和 queue 及容器适配器模式的介绍

文章目录 1. stack 的介绍和使用1.1 stack 的介绍1.2 stack 的接口及使用1.3 stack 的模拟实现 2. queue 的介绍和使用2.1 queue 的介绍2.2 queue 的接口及使用2.3 queue 的模拟实现 3. priority_queue的介绍和使用3.1 priority_queue 的介绍3.2 priority_queue 的接口及使用3.…

windows 安装gdal实现png转tif,以及栅格拼接

windows 安装gdal实现png转tif,以及栅格拼接 一、安装gdal 网上有很多安装gdal的方法,此处通过osgeo4w安装gdal 1.下载osgeo4w 下载地址 https://trac.osgeo.org/osgeo4w/ 2、安装osgeo4w exe文件安装,前面部分很简单,就不再…

Socket.IO是什么?适用哪些场景?

Socket.IO 详细介绍及适用场景 一、Socket.IO 是什么? Socket.IO 是一个基于事件驱动的 实时通信库,支持双向、低延迟的客户端-服务器交互。它底层结合了 WebSocket 和 HTTP 长轮询 等技术,能够在不同网络环境下自动选择最优传输方式&#x…

深度学习入门:卷积神经网络

目录 1、整体结构2、卷积层2.1 全连接层存在的问题2.2 卷积运算2.3 填充2.4 步幅2.5 3维数据的卷积运算2.6 结合方块思考2.7 批处理 3、池化层4、卷积层和池化层的实现4.1 4维数组4.2 基于im2col的展开4.3 卷积层的实现4.4 池化层的实现 5、CNN的实现6、CNN的可视化6.1 第一层权…

【Odoo】Pycharm导入运行Odoo15

【Odoo】Pycharm导入运行Odoo15 前置准备1. Odoo-15项目下载解压2. PsrtgreSQL数据库 项目导入运行1. 项目导入2. 设置项目内虚拟环境3. 下载项目中依赖4. 修改配置文件odoo.conf 运行Pycharm快捷运行 前置准备 1. Odoo-15项目下载解压 将下载好的项目解压到开发目录下 2. …

pytest框架 - 第二集 allure报告

一、断言assert 二、Pytest 结合 allure-pytest 插件生成美观的 Allure 报告 (1) 安装 allure 环境 安装 allure-pytest 插件:pip install allure-pytest在 github 下载 allure 报告文件 地址:Releases allure-framework/allure2 GitHub下载&#x…

pycharm连接github(详细步骤)

【前提:菜鸟学习的记录过程,如果有不足之处,还请各位大佬大神们指教(感谢)】 1.先安装git 没有安装git的小伙伴,看上一篇安装git的文章。 安装git,2.49.0版本-CSDN博客 打开cmd(…

oracle linux 95 升级openssh 10 和openssl 3.5 过程记录

1. 安装操作系统,注意如果可以选择,选择安装开发工具,主要是后续需要编译安装,需要gcc 编译工具。 2. 安装操作系统后,检查zlib 、zlib-dev是否安装,如果没有,可以使用安装镜像做本地源安装&a…