通过Python实现批量修改文件名前后缀功能

作者:

文章目录
  • 要实现的功能其实很简单,通过Python代码获取文件夹的路径,通过循环处理该文件夹中所有文件的名称,之后对文件名进行更新即可,整个撰写代码是通过人工加上ai的方式进行的。
  • 完整的代码如下: import os import tkinter as tk from tkinter import filedialog from tkinter import ttk from tkinter import messagebox from tkinter import simpledialog # 验证文件名是否符合Windows规范(中文增强版) # 修改现有is_valid_filename函数 def is_valid_filename(text: str) -> bool: # 非法字符检测(保持原逻辑) illegal_chars = set(‘\/:*?”<>|’) if any(char in illegal_chars for char in text): return False # 保留名称检测(保持原逻辑) reserved_names = { ‘CON’, ‘PRN’, ‘AUX’, ‘NUL’, ‘COM1’, ‘COM2’, ‘COM3’, ‘COM4’, ‘COM5’, ‘COM6’, ‘COM7’, ‘COM8’, ‘COM9’, ‘LPT1’, ‘LPT2’, ‘LPT3’, ‘LPT4’, ‘LPT5’, ‘LPT6’, ‘LPT7’, ‘LPT8’, ‘LPT9’ } if text.upper() in reserved_names: return False # 增强中文处理 # 1. 检查全角字符是否包含非法字符(中文输入法可能输入全角字符) fullwidth_illegal = set(‘\/:*?"<>|’) # 全角非法字符 if any(char in fullwidth_illegal for char in text): return False # 2. 增强长度检测(基于字符数而非字节数) # Windows允许最多255个字符(包括中文) if len(text) > 255: return False # 3. 检查首尾空格(中文文件名常见问题) if text.strip() != text: return False # 4. 检查末尾点号(.test.txt. 这种形式) if text.endswith(‘.’) or text.startswith(‘.’): return False return True # 用文本框获取添加或者删除的字符串 def getTextbox(parent_window=None): # 通过全局控件获取父窗口 global path_entry # 声明使用全局路径输入框 parent_window = path_entry.winfo_toplevel() # 获取输入框所在的顶级窗口 # 添加循环输入机制 while True: content = simpledialog.askstring( “输入内容”, “请输入要添加的字符串(不能包含 \/:*?”<>| 等非法字符):”, # 添加提示 parent=parent_window ) print(“输入:”, content) # 用户取消输入 if content is None: return None # 验证逻辑 if not content: messagebox.showerror(“错误”, “输入不能为空!”) elif not is_valid_filename(content): messagebox.showerror(“错误”, f”文件名不合法!n” f”1. 请勿使用:\ / : * ? ” < > | 及其全角形式n” f”2. 不要使用CON、PRN等保留名称n” f”3. 长度不超过255字符(当前:{len(content)})n” f”4. 首尾不能有空格n” f”5. 不能以点号开头或结尾”) else: return content # 合法输入退出循环 # 新增文件夹浏览函数 def browse_folder(entry_widget): “””打开文件夹选择对话框””” folder_path = filedialog.askdirectory(title=’请选择要处理的文件夹’) if folder_path: # 清空并更新文本框内容 entry_widget.config(state=’normal’) entry_widget.delete(0, tk.END) entry_widget.insert(0, folder_path) entry_widget.config(state=’readonly’) # 可选:自动滚动到末尾 entry_widget.xview_moveto(1) # 定义确认事件处理 def on_confirm(): # print(“确认”) # 获取所有输入数据 folder_path = path_entry.get() selected_mode = mode_var.get() selected_separator = separator_var.get()[0] # 只要前一个英文字符即可 # 验证数据完整性 if not folder_path: messagebox.showerror(“警告”, “请先选择文件夹!”) # 选择文件夹名 browse_folder(path_entry) return # 打印结果 print(f”文件夹路径:{folder_path}”) print(f”操作模式:{selected_mode}”) print(f”分隔符:{selected_separator}”) # 获取要添加或者删除的文字,需要在循环外就确认了,因为只需要确认一次即可 content = getTextbox() # 输入为None不能继续运行了,否则会把None当做字符串进行拼接 if content is None: return # 新增文件处理逻辑(Listdir获取文件夹中所有文件和文件夹名称组成的列表) for filename in os.listdir(folder_path): # 获取文件路径(join拼接路径) file_path = os.path.join(folder_path, filename) if os.path.isfile(file_path): # 打印文件路径 # print(f”正在处理文件:{file_path}”) # 分割文件名和拓展名 base_name, ext = os.path.splitext(filename) # 根据模式处理文件名 if selected_mode == “添加前缀”: # 直接进行拼接操作 new_base = f”{content}{selected_separator}{base_name}” # print(new_base) elif selected_mode == “添加后缀”: new_base = f”{base_name}{selected_separator}{content}” elif selected_mode == “删除前缀”: # 格式验证:必须包含分割符且分割符在content之后 if base_name.startswith(f”{content}{selected_separator}”): # 计算前缀长度时考虑中文等宽字符问题 prefix_length = len(content) + len(selected_separator) new_base = base_name[prefix_length:] # 增加空文件名校验 if not new_base: print(f”警告:删除前缀后文件名为空,跳过 {filename}”) continue else: print(f”未找到匹配前缀:{content}{selected_separator}”) continue elif selected_mode == “删除后缀”: # 格式验证:必须严格以【分隔符+内容】结尾 suffix_pattern = f”{selected_separator}{content}” if base_name.endswith(suffix_pattern): # 计算后缀长度(考虑多语言字符) suffix_length = len(suffix_pattern) new_base = base_name[:-suffix_length] # 空文件名防御机制 if not new_base.strip(): # 处理纯空白字符情况 print(f”危险操作:删除后缀后文件名为空,跳过 {filename}”) continue else: print(f”未找到匹配后缀:{suffix_pattern}”) continue # 拼接新的文件名 new_name = f”{new_base}{ext}” # 拼接新的文件路径 new_path = os.path.join(folder_path, new_name) # 检测文件名冲突 if os.path.exists(new_path): # 弹出二次确认对话框 confirm = messagebox.askyesno( “确认覆盖”, f”文件 ‘{new_name}’ 已存在!n” f”原文件:{filename}n” f”新文件:{new_name}nn” “是否覆盖已有文件?”, icon=’warning’ ) if not confirm: print(f”跳过已存在文件:{new_name}”) continue # 执行重命名操作 try: os.replace(file_path, new_path) # 自动覆盖已存在的文件 print(f”成功重命名:{filename} -> {new_name}”) except Exception as e: messagebox.showerror(“重命名错误”, f”无法重命名 {filename}:n{str(e)}n” “可能原因:n” “1. 文件正在被其他程序使用n” “2. 没有写入权限n” “3. 文件名包含系统保留字符”) break # 遇到错误中止处理 # 定义界面展示的组件 def module(window): global path_entry, mode_var, separator_var # 声明全局变量(因为后续在其他函数中需要使用到这些参数) # 初始化默认值 mode_var = tk.StringVar(value=”添加前缀”) separator_var = tk.StringVar(value=” _下划线”) ######################################################################################################### # 新增创建路径选择容器(顶部区域) path_frame = tk.Frame(window) path_frame.pack(side=tk.TOP, pady=20) # 创建只读文本框 path_entry = tk.Entry(path_frame, width=65, font=(“仿宋”, 12, “bold”), state=”readonly”, readonlybackground=”white”) path_entry.pack(side=tk.LEFT, padx=5, ipady=25) # 创建浏览按钮 browse_button = tk.Button(path_frame, text=”获取文件夹名”, width=100, height=2, bg=”#2196F3″, fg=”white”, font=(“仿宋”, 18, “bold”), command=lambda: browse_folder(path_entry)) browse_button.pack(side=tk.RIGHT, padx=5) ######################################################################################################### # 增加操作模式选择区域 mode_frame = tk.Frame(window) mode_frame.pack(fill=tk.X, pady=20) # 模式选择标签 mode_label = tk.Label(mode_frame, text=”操作模式:”, font=(“仿宋”, 28, “bold”), width=15) mode_label.pack(side=tk.LEFT, padx=5) # 下拉框选项数据 mode_options = [“添加前缀”, “添加后缀”, “删除前缀”, “删除后缀”] # 创建下拉框(要用textvariable=mode_var绑定数据,不然不会更新) mode_combobox = ttk.Combobox(mode_frame, values=mode_options, width=30, style=’Centered.TCombobox’, justify=”center”, state=”readonly”, font=(“仿宋”, 28, “bold”), textvariable=mode_var) mode_combobox.pack(side=tk.LEFT, padx=15) mode_combobox.current(0) # 设置默认选中 ######################################################################################################### # 增加常见分割符区域 mode_frame = tk.Frame(window) mode_frame.pack(fill=tk.X, pady=20) # 模式选择标签 mode_label = tk.Label(mode_frame, text=”常见分割符”, font=(“仿宋”, 28, “bold”), width=15, anchor=”center”) mode_label.pack(side=tk.LEFT, padx=5) # 下拉框选项数据 mode_options = [“_下划线”, “-连字符”, “.点号”, ” 空格”] # 创建下拉框(新增绑定textvariable=separator_var) mode_combobox = ttk.Combobox(mode_frame, values=mode_options, width=30, style=’Centered.TCombobox’, font=(“仿宋”, 28, “bold”), state=”readonly”, justify=”center”, textvariable=separator_var) mode_combobox.pack(side=tk.LEFT, padx=15) mode_combobox.current(0) # 设置默认选中 ######################################################################################################### # 给界面添加确认和取消的按钮 # 创建按钮容器框架(实现更灵活的布局控制) button_frame = tk.Frame(window) # 固定在窗口底部并设置纵向间距 button_frame.pack(side=tk.BOTTOM, pady=20) # 创建确认和取消按钮 confirm_button = tk.Button(button_frame, text=”确认”, width=12, height=2, bg=”#4CAF50″, fg=”white”, font=(“仿宋”, 18, “bold”), command=lambda: on_confirm()) # 绑定确认事件处理 cancel_button = tk.Button(button_frame, text=”取消”, width=12, height=2, bg=”#F44336″, fg=”white”, font=(“仿宋”, 18, “bold”), command=lambda: window.destroy()) # 直接绑定关闭窗口的事件 # 确认按钮(添加pack布局) confirm_button.pack(side=tk.LEFT, padx=10, ipady=5) # 取消按钮(添加pack布局) cancel_button.pack(side=tk.RIGHT, padx=10, ipady=5) # 定义界面框架 class Frame: # 创建窗口 window = tk.Tk() # 在Frame类初始化前添加样式配置代码 style = ttk.Style() # 设置主题为clam style.theme_use(‘clam’) # 配置下拉框主体样式 style.configure(‘Centered.TCombobox’, justify=”center”, foreground=”#2c3e50″, fieldbackground=”white”, padding=(0, 15), anchor=”center”, state=”readonly”) # 配置下拉列表的样式 style.configure(‘Centered.TCombobox.Listbox’, foreground=”#2c3e50″, rowheight=30, anchor=”center”) # 设置标题 window.title(“文件批量重命名工具”) # 获取屏幕大小 screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() # 计算所需窗口的相对大小 relative_width = int(screen_width * 0.5) relative_height = int(screen_height * 0.5) # 计算窗口位于屏幕中央的坐标 relative_x = (screen_width – relative_width) // 2 relative_y = (screen_height – relative_height) // 2 # 应用窗口尺寸和位置(格式:宽度x高度+X坐标+Y坐标) window.geometry(f”{relative_width}x{relative_height}+{relative_x}+{relative_y}”) # 应用组件 module(window) # 运行窗口 window.mainloop() def main(): # 创建窗口 Frame() if __name__ == “__main__”: main()
  • 原始文件名 选择“操作模式”以及“常见分割符”,后点击“确认”按钮,在输入框中输入需要添加或者删除的字符串。 pycharm中的输出: 结果如下图所示:  添加后缀操作: 这里之前出现了一个问题,如果文本框没有输入的话,他会返回None,然后把None当做字符串进行拼接,这里需要避免这种情况。 # 输入为None不能继续运行了,否则会把None当做字符串进行拼接 if content is None: return 对于后续还可以通过修改代码批量修改文件的扩展名。 以上就是通过Python实现批量修改文件名前后缀功能的详细内容,更多关于Python批量修改文件名前后缀的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python批量修改文件名操作指南(文件名的替换、前缀、后缀的添加) python使用正则表达式来获取文件名的前缀方法 python读取文件名及后缀详解 python 分离文件名和路径以及分离文件名和后缀的方法 Python批量修改文件名案例汇总
  • 目录
    • 功能实现
      • 添加
      • 删除
    • 图形界面
      • 定义界面
      • 定义组件
    • 完整代码
      • 测试

        要实现的功能其实很简单,通过Python代码获取文件夹的路径,通过循环处理该文件夹中所有文件的名称,之后对文件名进行更新即可,整个撰写代码是通过人工加上ai的方式进行的。

        添加前后缀,直接对原始的字符串进行拼接即可,中间通过分割符来分割,对于添加的字符串不论中文还是英文都需要满足windows系统文件命名的规范,项目中通过ai实现了验证过程,但是可能还是不完善。

        # 添加前缀 
        new_base = f"{content}{selected_separator}{base_name}"
        # 添加后缀
        new_base = f"{base_name}{selected_separator}{content}"

         重命名操作

        # 执行重命名操作
        try:
            os.replace(file_path, new_path)  # 自动覆盖已存在的文件
            print(f"成功重命名:{filename} -> {new_name}")
        except Exception as e:
            messagebox.showerror("重命名错误",
                                 f"无法重命名 {filename}:n{str(e)}n"
                                  "可能原因:n"
                                  "1. 文件正在被其他程序使用n"
                                  "2. 没有写入权限n"
                                  "3. 文件名包含系统保留字符")
             break  # 遇到错误中止处理

        删除前后缀即对字符串进行分割操作。 

        # 删除前缀使用split(从左分割)
        parts = base_name.split(f"{content}{selected_separator}", 1)
        # 删除后缀使用rsplit(从右分割)
        parts = base_name.rsplit(f"{selected_separator}{content}", 1)

        没想到这么快在使用过程中出现问题 ,这个直接分割可能出现中间截取的情况,比如“专题01 物质的组成、性质、分类与化学用语(讲)(原卷+解析版)”这个文件名,如果我是要删除后缀“ 物质”,这个肯定是无法找到的,但是如果是截取,他则会只保留“专题01”。

        修改代码如下:

                    elif selected_mode == "删除前缀":
                        # 格式验证:必须包含分割符且分割符在content之后
                        if base_name.startswith(f"{content}{selected_separator}"):
                            # 计算前缀长度时考虑中文等宽字符问题
                            prefix_length = len(content) + len(selected_separator)
                            new_base = base_name[prefix_length:]
         
                            # 增加空文件名校验
                            if not new_base:
                                print(f"警告:删除前缀后文件名为空,跳过 {filename}")
                                continue
                        else:
                            print(f"未找到匹配前缀:{content}{selected_separator}")
                            continue
                    elif selected_mode == "删除后缀":
                        # 格式验证:必须严格以【分隔符+内容】结尾
                        suffix_pattern = f"{selected_separator}{content}"
                        if base_name.endswith(suffix_pattern):
                            # 计算后缀长度(考虑多语言字符)
                            suffix_length = len(suffix_pattern)
                            new_base = base_name[:-suffix_length]
         
                            # 空文件名防御机制
                            if not new_base.strip():  # 处理纯空白字符情况
                                print(f"危险操作:删除后缀后文件名为空,跳过 {filename}")
                                continue
                        else:
                            print(f"未找到匹配后缀:{suffix_pattern}")
                            continue

        当然在删除前还需要对文件名进行验证,看是否有符合的前后缀以及是否和其他文件名冲突。

        # 前缀验证
        if f"{content}{selected_separator}" in base_name:

         不论是添加还是删除操作都需要检测文件名是否冲突。

        # 检测文件名冲突
        if os.path.exists(new_path):
            # 弹出二次确认对话框
            confirm = messagebox.askyesno(
                "确认覆盖",
                f"文件 '{new_name}' 已存在!n"
                f"原文件:{filename}n"
                f"新文件:{new_name}nn"
                "是否覆盖已有文件?",
                icon='warning'
             )
             if not confirm:
                 print(f"跳过已存在文件:{new_name}")
                 continue

        对于这些框架的代码,使用ai还是比较容易实现,就是调试起来有点麻烦,不能无脑丢给ai,还需要自己进行分析,通过电脑界面来对窗口的界面和位置进行设置。

        # 定义界面框架
        class Frame:
            # 创建窗口
            window = tk.Tk()
            # 在Frame类初始化前添加样式配置代码
            style = ttk.Style()
            # 设置主题为clam
            style.theme_use('clam')
            # 配置下拉框主体样式
            style.configure('Centered.TCombobox', justify="center", foreground="#2c3e50",
                            fieldbackground="white", padding=(0, 15), anchor="center", state="readonly")
            # 配置下拉列表的样式
            style.configure('Centered.TCombobox.Listbox', foreground="#2c3e50",
                            rowheight=30, anchor="center")
            # 设置标题
            window.title("文件批量重命名工具")
            # 获取屏幕大小
            screen_width = window.winfo_screenwidth()
            screen_height = window.winfo_screenheight()
            # 计算所需窗口的相对大小
            relative_width = int(screen_width * 0.5)
            relative_height = int(screen_height * 0.5)
            # 计算窗口位于屏幕中央的坐标
            relative_x = (screen_width - relative_width) // 2
            relative_y = (screen_height - relative_height) // 2
            # 应用窗口尺寸和位置(格式:宽度x高度+X坐标+Y坐标)
            window.geometry(f"{relative_width}x{relative_height}+{relative_x}+{relative_y}")
            # 应用组件
            module(window)
            # 运行窗口
            window.mainloop()

        主要就是涉及到了文本框、按钮和下拉框的布局,需要对文本框修改成只读的属性,文件夹路径

        操作模式和分割符就没有进行是否规范的判断。

        def module(window):
            global path_entry, mode_var, separator_var  # 声明全局变量(因为后续在其他函数中需要使用到这些参数)
            # 初始化默认值
            mode_var = tk.StringVar(value="添加前缀")
            separator_var = tk.StringVar(value=" _下划线")
            #########################################################################################################
            # 新增创建路径选择容器(顶部区域)
            path_frame = tk.Frame(window)
            path_frame.pack(side=tk.TOP, pady=20)
            # 创建只读文本框
            path_entry = tk.Entry(path_frame, width=65, font=("仿宋", 12, "bold"), state="readonly",
                                  readonlybackground="white")
            path_entry.pack(side=tk.LEFT, padx=5, ipady=25)
            # 创建浏览按钮
            browse_button = tk.Button(path_frame, text="获取文件夹名", width=100, height=2, bg="#2196F3", fg="white",
                                      font=("仿宋", 18, "bold"), command=lambda: browse_folder(path_entry))
            browse_button.pack(side=tk.RIGHT, padx=5)
            #########################################################################################################
            # 增加操作模式选择区域
            mode_frame = tk.Frame(window)
            mode_frame.pack(fill=tk.X, pady=20)
            # 模式选择标签
            mode_label = tk.Label(mode_frame, text="操作模式:", font=("仿宋", 28, "bold"), width=15)
            mode_label.pack(side=tk.LEFT, padx=5)
            # 下拉框选项数据
            mode_options = ["添加前缀", "添加后缀", "删除前缀", "删除后缀"]
            # 创建下拉框(要用textvariable=mode_var绑定数据,不然不会更新)
            mode_combobox = ttk.Combobox(mode_frame, values=mode_options, width=30, style='Centered.TCombobox',
                                         justify="center", state="readonly", font=("仿宋", 28, "bold"), textvariable=mode_var)
            mode_combobox.pack(side=tk.LEFT, padx=15)
            mode_combobox.current(0)  # 设置默认选中
            #########################################################################################################
            # 增加常见分割符区域
            mode_frame = tk.Frame(window)
            mode_frame.pack(fill=tk.X, pady=20)
            # 模式选择标签
            mode_label = tk.Label(mode_frame, text="常见分割符", font=("仿宋", 28, "bold"), width=15, anchor="center")
            mode_label.pack(side=tk.LEFT, padx=5)
            # 下拉框选项数据
            mode_options = ["_下划线", "-连字符", ".点号", " 空格"]
            # 创建下拉框(新增绑定textvariable=separator_var)
            mode_combobox = ttk.Combobox(mode_frame, values=mode_options, width=30, style='Centered.TCombobox',
                                         font=("仿宋", 28, "bold"), state="readonly", justify="center",
                                         textvariable=separator_var)
            mode_combobox.pack(side=tk.LEFT, padx=15)
            mode_combobox.current(0)  # 设置默认选中
            #########################################################################################################
            # 给界面添加确认和取消的按钮
            # 创建按钮容器框架(实现更灵活的布局控制)
            button_frame = tk.Frame(window)
            # 固定在窗口底部并设置纵向间距
            button_frame.pack(side=tk.BOTTOM, pady=20)
            # 创建确认和取消按钮
            confirm_button = tk.Button(button_frame, text="确认", width=12, height=2, bg="#4CAF50", fg="white",
                                       font=("仿宋", 18, "bold"), command=lambda: on_confirm())  # 绑定确认事件处理
            cancel_button = tk.Button(button_frame, text="取消", width=12, height=2, bg="#F44336", fg="white",
                                      font=("仿宋", 18, "bold"),
                                      command=lambda: window.destroy())  # 直接绑定关闭窗口的事件
            # 确认按钮(添加pack布局)
            confirm_button.pack(side=tk.LEFT, padx=10, ipady=5)
            # 取消按钮(添加pack布局)
            cancel_button.pack(side=tk.RIGHT, padx=10, ipady=5)

        系统界面如下图所示

        完整的代码如下:

        import os
        import tkinter as tk
        from tkinter import filedialog
        from tkinter import ttk
        from tkinter import messagebox
        from tkinter import simpledialog
         
         
        # 验证文件名是否符合Windows规范(中文增强版)
        # 修改现有is_valid_filename函数
        def is_valid_filename(text: str) -> bool:
            # 非法字符检测(保持原逻辑)
            illegal_chars = set('\/:*?"<>|')
            if any(char in illegal_chars for char in text):
                return False
         
            # 保留名称检测(保持原逻辑)
            reserved_names = {
                'CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3',
                'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
                'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6',
                'LPT7', 'LPT8', 'LPT9'
            }
            if text.upper() in reserved_names:
                return False
         
            # 增强中文处理
            # 1. 检查全角字符是否包含非法字符(中文输入法可能输入全角字符)
            fullwidth_illegal = set('\/:*?"<>|')  # 全角非法字符
            if any(char in fullwidth_illegal for char in text):
                return False
         
            # 2. 增强长度检测(基于字符数而非字节数)
            # Windows允许最多255个字符(包括中文)
            if len(text) > 255:
                return False
         
            # 3. 检查首尾空格(中文文件名常见问题)
            if text.strip() != text:
                return False
         
            # 4. 检查末尾点号(.test.txt. 这种形式)
            if text.endswith('.') or text.startswith('.'):
                return False
         
            return True
         
         
        # 用文本框获取添加或者删除的字符串
        def getTextbox(parent_window=None):
            # 通过全局控件获取父窗口
            global path_entry  # 声明使用全局路径输入框
            parent_window = path_entry.winfo_toplevel()  # 获取输入框所在的顶级窗口
         
            # 添加循环输入机制
            while True:
                content = simpledialog.askstring(
                    "输入内容",
                    "请输入要添加的字符串(不能包含 \/:*?"<>| 等非法字符):",  # 添加提示
                    parent=parent_window
                )
                print("输入:", content)
                # 用户取消输入
                if content is None:
                    return None
         
                # 验证逻辑
                if not content:
                    messagebox.showerror("错误", "输入不能为空!")
                elif not is_valid_filename(content):
                    messagebox.showerror("错误",
                                         f"文件名不合法!n"
                                         f"1. 请勿使用:\ / : * ? " < > | 及其全角形式n"
                                         f"2. 不要使用CON、PRN等保留名称n"
                                         f"3. 长度不超过255字符(当前:{len(content)})n"
                                         f"4. 首尾不能有空格n"
                                         f"5. 不能以点号开头或结尾")
                else:
                    return content  # 合法输入退出循环
         
         
        # 新增文件夹浏览函数
        def browse_folder(entry_widget):
            """打开文件夹选择对话框"""
            folder_path = filedialog.askdirectory(title='请选择要处理的文件夹')
            if folder_path:
                # 清空并更新文本框内容
                entry_widget.config(state='normal')
                entry_widget.delete(0, tk.END)
                entry_widget.insert(0, folder_path)
                entry_widget.config(state='readonly')
                # 可选:自动滚动到末尾
                entry_widget.xview_moveto(1)
         
         
        # 定义确认事件处理
        def on_confirm():
            # print("确认")
            # 获取所有输入数据
            folder_path = path_entry.get()
            selected_mode = mode_var.get()
            selected_separator = separator_var.get()[0]  # 只要前一个英文字符即可
         
            # 验证数据完整性
            if not folder_path:
                messagebox.showerror("警告", "请先选择文件夹!")
                # 选择文件夹名
                browse_folder(path_entry)
                return
         
            # 打印结果
            print(f"文件夹路径:{folder_path}")
            print(f"操作模式:{selected_mode}")
            print(f"分隔符:{selected_separator}")
         
            # 获取要添加或者删除的文字,需要在循环外就确认了,因为只需要确认一次即可
            content = getTextbox()
         
            # 输入为None不能继续运行了,否则会把None当做字符串进行拼接
            if content is None:
                return
            # 新增文件处理逻辑(Listdir获取文件夹中所有文件和文件夹名称组成的列表)
            for filename in os.listdir(folder_path):
                # 获取文件路径(join拼接路径)
                file_path = os.path.join(folder_path, filename)
                if os.path.isfile(file_path):
                    # 打印文件路径
                    # print(f"正在处理文件:{file_path}")
                    # 分割文件名和拓展名
                    base_name, ext = os.path.splitext(filename)
                    # 根据模式处理文件名
                    if selected_mode == "添加前缀":
                        # 直接进行拼接操作
                        new_base = f"{content}{selected_separator}{base_name}"
                        # print(new_base)
                    elif selected_mode == "添加后缀":
                        new_base = f"{base_name}{selected_separator}{content}"
                    elif selected_mode == "删除前缀":
                        # 格式验证:必须包含分割符且分割符在content之后
                        if base_name.startswith(f"{content}{selected_separator}"):
                            # 计算前缀长度时考虑中文等宽字符问题
                            prefix_length = len(content) + len(selected_separator)
                            new_base = base_name[prefix_length:]
         
                            # 增加空文件名校验
                            if not new_base:
                                print(f"警告:删除前缀后文件名为空,跳过 {filename}")
                                continue
                        else:
                            print(f"未找到匹配前缀:{content}{selected_separator}")
                            continue
                    elif selected_mode == "删除后缀":
                        # 格式验证:必须严格以【分隔符+内容】结尾
                        suffix_pattern = f"{selected_separator}{content}"
                        if base_name.endswith(suffix_pattern):
                            # 计算后缀长度(考虑多语言字符)
                            suffix_length = len(suffix_pattern)
                            new_base = base_name[:-suffix_length]
         
                            # 空文件名防御机制
                            if not new_base.strip():  # 处理纯空白字符情况
                                print(f"危险操作:删除后缀后文件名为空,跳过 {filename}")
                                continue
                        else:
                            print(f"未找到匹配后缀:{suffix_pattern}")
                            continue
         
                # 拼接新的文件名
                new_name = f"{new_base}{ext}"
                # 拼接新的文件路径
                new_path = os.path.join(folder_path, new_name)
                # 检测文件名冲突
                if os.path.exists(new_path):
                    # 弹出二次确认对话框
                    confirm = messagebox.askyesno(
                        "确认覆盖",
                        f"文件 '{new_name}' 已存在!n"
                        f"原文件:{filename}n"
                        f"新文件:{new_name}nn"
                        "是否覆盖已有文件?",
                        icon='warning'
                    )
                    if not confirm:
                        print(f"跳过已存在文件:{new_name}")
                        continue
                # 执行重命名操作
                try:
                    os.replace(file_path, new_path)  # 自动覆盖已存在的文件
                    print(f"成功重命名:{filename} -> {new_name}")
                except Exception as e:
                    messagebox.showerror("重命名错误",
                                         f"无法重命名 {filename}:n{str(e)}n"
                                         "可能原因:n"
                                         "1. 文件正在被其他程序使用n"
                                         "2. 没有写入权限n"
                                         "3. 文件名包含系统保留字符")
                    break  # 遇到错误中止处理
         
         
        # 定义界面展示的组件
        def module(window):
            global path_entry, mode_var, separator_var  # 声明全局变量(因为后续在其他函数中需要使用到这些参数)
            # 初始化默认值
            mode_var = tk.StringVar(value="添加前缀")
            separator_var = tk.StringVar(value=" _下划线")
            #########################################################################################################
            # 新增创建路径选择容器(顶部区域)
            path_frame = tk.Frame(window)
            path_frame.pack(side=tk.TOP, pady=20)
            # 创建只读文本框
            path_entry = tk.Entry(path_frame, width=65, font=("仿宋", 12, "bold"), state="readonly",
                                  readonlybackground="white")
            path_entry.pack(side=tk.LEFT, padx=5, ipady=25)
            # 创建浏览按钮
            browse_button = tk.Button(path_frame, text="获取文件夹名", width=100, height=2, bg="#2196F3", fg="white",
                                      font=("仿宋", 18, "bold"), command=lambda: browse_folder(path_entry))
            browse_button.pack(side=tk.RIGHT, padx=5)
            #########################################################################################################
            # 增加操作模式选择区域
            mode_frame = tk.Frame(window)
            mode_frame.pack(fill=tk.X, pady=20)
            # 模式选择标签
            mode_label = tk.Label(mode_frame, text="操作模式:", font=("仿宋", 28, "bold"), width=15)
            mode_label.pack(side=tk.LEFT, padx=5)
            # 下拉框选项数据
            mode_options = ["添加前缀", "添加后缀", "删除前缀", "删除后缀"]
            # 创建下拉框(要用textvariable=mode_var绑定数据,不然不会更新)
            mode_combobox = ttk.Combobox(mode_frame, values=mode_options, width=30, style='Centered.TCombobox',
                                         justify="center", state="readonly", font=("仿宋", 28, "bold"), textvariable=mode_var)
            mode_combobox.pack(side=tk.LEFT, padx=15)
            mode_combobox.current(0)  # 设置默认选中
            #########################################################################################################
            # 增加常见分割符区域
            mode_frame = tk.Frame(window)
            mode_frame.pack(fill=tk.X, pady=20)
            # 模式选择标签
            mode_label = tk.Label(mode_frame, text="常见分割符", font=("仿宋", 28, "bold"), width=15, anchor="center")
            mode_label.pack(side=tk.LEFT, padx=5)
            # 下拉框选项数据
            mode_options = ["_下划线", "-连字符", ".点号", " 空格"]
            # 创建下拉框(新增绑定textvariable=separator_var)
            mode_combobox = ttk.Combobox(mode_frame, values=mode_options, width=30, style='Centered.TCombobox',
                                         font=("仿宋", 28, "bold"), state="readonly", justify="center",
                                         textvariable=separator_var)
            mode_combobox.pack(side=tk.LEFT, padx=15)
            mode_combobox.current(0)  # 设置默认选中
            #########################################################################################################
            # 给界面添加确认和取消的按钮
            # 创建按钮容器框架(实现更灵活的布局控制)
            button_frame = tk.Frame(window)
            # 固定在窗口底部并设置纵向间距
            button_frame.pack(side=tk.BOTTOM, pady=20)
            # 创建确认和取消按钮
            confirm_button = tk.Button(button_frame, text="确认", width=12, height=2, bg="#4CAF50", fg="white",
                                       font=("仿宋", 18, "bold"), command=lambda: on_confirm())  # 绑定确认事件处理
            cancel_button = tk.Button(button_frame, text="取消", width=12, height=2, bg="#F44336", fg="white",
                                      font=("仿宋", 18, "bold"),
                                      command=lambda: window.destroy())  # 直接绑定关闭窗口的事件
            # 确认按钮(添加pack布局)
            confirm_button.pack(side=tk.LEFT, padx=10, ipady=5)
            # 取消按钮(添加pack布局)
            cancel_button.pack(side=tk.RIGHT, padx=10, ipady=5)
         
         
        # 定义界面框架
        class Frame:
            # 创建窗口
            window = tk.Tk()
            # 在Frame类初始化前添加样式配置代码
            style = ttk.Style()
            # 设置主题为clam
            style.theme_use('clam')
            # 配置下拉框主体样式
            style.configure('Centered.TCombobox', justify="center", foreground="#2c3e50",
                            fieldbackground="white", padding=(0, 15), anchor="center", state="readonly")
            # 配置下拉列表的样式
            style.configure('Centered.TCombobox.Listbox', foreground="#2c3e50",
                            rowheight=30, anchor="center")
            # 设置标题
            window.title("文件批量重命名工具")
            # 获取屏幕大小
            screen_width = window.winfo_screenwidth()
            screen_height = window.winfo_screenheight()
            # 计算所需窗口的相对大小
            relative_width = int(screen_width * 0.5)
            relative_height = int(screen_height * 0.5)
            # 计算窗口位于屏幕中央的坐标
            relative_x = (screen_width - relative_width) // 2
            relative_y = (screen_height - relative_height) // 2
            # 应用窗口尺寸和位置(格式:宽度x高度+X坐标+Y坐标)
            window.geometry(f"{relative_width}x{relative_height}+{relative_x}+{relative_y}")
            # 应用组件
            module(window)
            # 运行窗口
            window.mainloop()
         
         
        def main():
            # 创建窗口
            Frame()
         
         
        if __name__ == "__main__":
            main()

        原始文件名

        选择“操作模式”以及“常见分割符”,后点击“确认”按钮,在输入框中输入需要添加或者删除的字符串。

        pycharm中的输出:

        结果如下图所示: 

        添加后缀操作:

        这里之前出现了一个问题,如果文本框没有输入的话,他会返回None,然后把None当做字符串进行拼接,这里需要避免这种情况。

        # 输入为None不能继续运行了,否则会把None当做字符串进行拼接
        if content is None:
            return

        对于后续还可以通过修改代码批量修改文件的扩展名。

        以上就是通过Python实现批量修改文件名前后缀功能的详细内容,更多关于Python批量修改文件名前后缀的资料请关注风君子博客其它相关文章!

        您可能感兴趣的文章:

        • Python批量修改文件名操作指南(文件名的替换、前缀、后缀的添加)
        • python使用正则表达式来获取文件名的前缀方法
        • python读取文件名及后缀详解
        • python 分离文件名和路径以及分离文件名和后缀的方法
        • Python批量修改文件名案例汇总

        站内搜索