偷学一招, 玩转文件批量重命名工具

上次的文件批量重命名使用起来太麻烦,改进了一下

  • 添加界面使用更方便
  • 添加到右键菜单打开
  • 添加正则匹配
  • 添加修改历史记录,并支持撤销

先看效果

源代码

import os
import re
import sys
import time
import winreg
import tkinter as tk
from tkinter.filedialog import askdirectory


CUR_PATH = os.getcwd()
CUR_PROG = os.path.abspath(sys.argv[0])
HISTORY = []

def create_reg(path=CUR_PROG):
    """添加右键菜单注册表项"""
    key = winreg.CreateKeyEx(winreg.HKEY_CLASSES_ROOT, "Directory\\Background\\shell\\rename", 0, winreg.KEY_SET_VALUE)
    winreg.SetValueEx(key, "", 0, winreg.REG_SZ, "批量重命名")
    winreg.SetValueEx(key, "Icon", 0, winreg.REG_SZ, path)
    winreg.SetValue(key, "command", winreg.REG_SZ, path)
    # 关闭注册表键
    winreg.CloseKey(key)

def delete_reg(path):
    """删除右键菜单注册表项"""
    winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, "Directory\\Background\\shell\\rename\\command")
    winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, "Directory\\Background\\shell\\rename")
    print("删除注册表成功")



def replace_name(src: str, dst: str, count: int = -1, depth: int = 0, reg=False):
    success = []
    error = []
    # 遍历当前目录下的所有文件
    try:
        for root, dirs, files in os.walk(CUR_PATH, topdown=True):

            if root.count(os.sep) - CUR_PATH.count(os.sep) > 0 and depth==0:
                continue
            for name in files:
                if reg:
                    pattern = re.compile(rf"{src}", re.S)
                    new_name = pattern.sub(dst, name, count=0 if count < 0 else count)
                    print(pattern)
                    print(new_name)
                else:
                    new_name = name.replace(src, dst, count)
                src_name = os.path.join(root, name)
                dst_name = os.path.join(root, new_name)
                try:
                    if src_name != dst_name:
                        os.rename(src_name, dst_name)
                        success.append([src_name, dst_name])

                except Exception as e:
                    error.append([src_name, dst_name])
    finally:
        global HISTORY
        HISTORY.append([{"src": item[0], "dst": item[1]} for item in success])

    return success, error




def main():

    def replace():
        """在当前目录下批量重命名文件"""
        src = src_entry.get()
        dst = dst_entry.get()
        success, error = replace_name(src, dst, depth=dir_mode.get(), reg=reg_mode.get())
        error_info = "\n\n".join(["\n".join(item) for item in error])
        success_info = "\n\n".join(["\n".join(item) for item in success])
        history = f"\n\n{'='*20}{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}{'='*20}\n失败:{len(error)}\n{error_info}\n成功:{len(success)}\n{success_info}"
        history_entry.insert(tk.END, history)
        if len(HISTORY) > 0:
            undo_button.config(state=tk.NORMAL)

    
    def selectPath():
        path_ = askdirectory() #使用askdirectory()方法返回文件夹的路径
        if path_ == "":
            path.get() #当打开文件路径选择框后点击"取消" 输入框会清空路径,所以使用get()方法再获取一次路径
        else:
            path_ = path_.replace("/", "\\")  # 实际在代码中执行的路径为“\“ 所以替换一下
            global CUR_PATH
            CUR_PATH = path_
            path.set(path_)


    def openPath():
        dir = os.path.dirname(path.get()+"\\")
        os.system('start ' + dir)

    def undo():
        """撤销重命名"""
        cur = HISTORY.pop()
        for item in cur:
            os.rename(item.get("dst"), item.get("src"))
        if len(HISTORY) == 0:
            undo_button.config(state=tk.DISABLED)

    root = tk.Tk()
    root.title("批量重命名")
    root.geometry("500x300")
    # 设置窗口最大大小
    root.minsize(400, 200)
    root.maxsize(800, 600)


    path = tk.StringVar()
    path.set(CUR_PATH)

    row1 = tk.Frame(root, height=30)
    row2 = tk.Frame(root, height=30)
    row3 = tk.Frame(root, height=30)
    row4 = tk.Frame(root, height=30)
    row5 = tk.Frame(root, height=30)
    row1.pack(fill="x", pady=5)
    row2.pack(fill="x", pady=5)
    row3.pack(fill="x", pady=5)
    row4.pack(fill="x", pady=5)
    row5.pack(fill="x", pady=5)



    # 文件夹层级模式
    dir_mode = tk.IntVar(value=0)
    dir_label = tk.Label(row1, text='文件夹层级: ')
    dir_radio1 = tk.Radiobutton(row1, text='当前', value=0, variable=dir_mode, relief=tk.RAISED)
    dir_radio2 = tk.Radiobutton(row1, text='递归', value=1, variable=dir_mode, relief=tk.RAISED)
    dir_label.pack(side=tk.LEFT, padx=5)
    dir_radio1.pack(side=tk.LEFT, padx=0)
    dir_radio2.pack(side=tk.LEFT, padx=5)
    
    # 替换模式
    reg_mode = tk.IntVar(value=0)
    reg_label = tk.Label(row1, text='替换模式: ')
    reg_radio1 = tk.Radiobutton(row1, text='普通', value=0, variable=reg_mode, relief=tk.RAISED)
    reg_radio2 = tk.Radiobutton(row1, text='正则', value=1, variable=reg_mode, relief=tk.RAISED)
    reg_label.pack(side=tk.LEFT, padx=5)
    reg_radio1.pack(side=tk.LEFT, padx=0)
    reg_radio2.pack(side=tk.LEFT, padx=5)

    # 加入右键菜单
    add_menu_button = tk.Button(row1, text="加入右键菜单", command=create_reg)
    add_menu_button.pack(side=tk.RIGHT, anchor=tk.E, padx=5) # 0行0列

    # 目标路径
    path_label = tk.Label(row2, text="目标路径:")
    path_entry = tk.Entry(row2, textvariable=path, state="readonly")
    path_sbtn = tk.Button(row2, text="路径选择", command=selectPath)
    path_obtn = tk.Button(row2, text="打开文件位置", command=openPath)

    path_label.pack(side=tk.LEFT, padx=5)
    path_entry.pack(side=tk.LEFT, padx=5, expand=True, fill="x")
    path_sbtn.pack(side=tk.LEFT, padx=5)
    path_obtn.pack(side=tk.LEFT, padx=5)

    # 源字符串 目标字符串
    src_label = tk.Label(row3, text="源字符:")
    dst_label = tk.Label(row3, text="目标字符:")
    src_entry = tk.Entry(row3)
    dst_entry = tk.Entry(row3)

    src_label.pack(side=tk.LEFT, padx=5)
    src_entry.pack(side=tk.LEFT, padx=5, expand=True, fill="x") 
    dst_label.pack(side=tk.LEFT, padx=5)
    dst_entry.pack(side=tk.LEFT, padx=5, expand=True, fill="x")

    # 提交按扭
    undo_button = tk.Button(row4, text="撤销", state=tk.DISABLED, command=undo)
    submit_button = tk.Button(row4, text="开始替换", command=replace)
    submit_button.pack(side=tk.RIGHT, padx=5)
    undo_button.pack(side=tk.RIGHT, padx=5)


    # 操作记录
    history_entry = tk.Text(row5)
    history_entry.pack(side=tk.TOP, padx=5)


    root.mainloop()


if __name__ == "__main__":
    main()

打包

pyinstaller -Fw rename.py

 

加入右键菜单需要以管理员权限打开 

🌐本文链接:https://wizops.net/archives/202405/328.html(转载时请注明本文出处及文章链接)
⚠️本站部分资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
⚠️本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
💌联系方式: [email protected]
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇