python 批量修改字符串(文件夹名称、文件名称、文件内容)

 

# system module
import os
import re
import tkinter
import tkinter.messagebox
import tkinter.filedialog
import tkinter.ttk
import sys
import logging

logger = logging.getLogger(__name__)

def create_logger(filename="log.txt", level=logging.INFO, console_swtich = True):
    # 获取logger实例,如果参数为空则返回root logger
    # logger = logging.getLogger(__name__)

    # 创建日志输出格式
    formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d][%(funcName)s] - %(levelname)s - %(message)s")

    # 指定输出的文件路径
    file_handler = logging.FileHandler(filename)
    # 设置文件处理器格式
    file_handler.setFormatter(formatter)

    # 为logger添加的日志处理器
    logger.addHandler(file_handler)

    # 控制台日志
    if console_swtich:
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.formatter = formatter
        logger.addHandler(console_handler)

    # 指定日志的最低输出级别,默认为warn级别
    logger.setLevel(level)

    return logger

class modify_string():
    #界面布局方法
    def __init__(self):
        #创建界面,并且保存到成员属性中
        self.root = tkinter.Tk()
        self.root.minsize(400, 170)
        self.root.resizable(0, 0)
        self.root.title("批量修改字符串")

        #文件夹路径
        self.path = tkinter.StringVar()
        self.path.set("")

        #选项
        self.folder_name = tkinter.IntVar()
        self.file_name = tkinter.IntVar()
        self.file_content = tkinter.IntVar()

        #字符串
        self.string_old = tkinter.StringVar()
        self.string_new = tkinter.StringVar()

        #进度
        self.progress = tkinter.StringVar()
        self.progress.set("开始修改")

        #界面布局
        self.menus()
        self.layout()
        self.root.mainloop()

    def menus(self):
        #添加菜单

        #创建总菜单
        allmenu = tkinter.Menu(self.root)

        # 添加子菜单1
        debugmenu = tkinter.Menu(allmenu, tearoff=0)
        debugmenu.add_command(label="日志",
                              command=self.log)

        allmenu.add_cascade(label="调试",
                            menu=debugmenu)

        # 添加子菜单2
        helpmenu = tkinter.Menu(allmenu, tearoff=0)

        # 添加选项卡
        helpmenu.add_command(label='规则',
                             command=self.rule)
        helpmenu.add_command(label='版本说明',
                             command=self.release_note)
        helpmenu.add_command(label='关于',
                             command=self.about)

        allmenu.add_cascade(label='帮助',
                            menu=helpmenu)

        tkinter.ttk.Separator(self.root, orient="horizontal").pack(fill="x", padx=0)


        self.root.config(menu=allmenu)

    def layout(self):
        #布局
        #文件夹路径
        path_description = tkinter.Label(self.root,
                                         font=("宋体", 10),
                                         fg="blue",
                                         anchor="w",
                                         text="文件夹路径")
        path_description.place(x=5, y=10, width=70, height=20)

        path_show = tkinter.Label(self.root,
                                  bd=3,
                                  bg='white',
                                  font=("宋体", 10),
                                  anchor="e",
                                  textvariable=self.path)
        path_show.place(x=80, y=10, width=250, height=20)

        button_path = tkinter.Button(self.root,
                                     text='选择',
                                     command=self.select_path)
        button_path.place(x=335, y=10, width=60, height=20)

        # 选项
        option = tkinter.Label(self.root,
                               font=("宋体", 10),
                               fg="blue",
                               anchor="w",
                               text="修改选项")
        option.place(x=5, y=40, width=70, height=20)

        folder_select =tkinter.Checkbutton(self.root,
                                           text="文件夹名称",
                                           anchor="w",
                                           variable=self.folder_name)
        folder_select.place(x=80, y=40, width=100, height=20)

        folder_select = tkinter.Checkbutton(self.root,
                                            text="文件名称",
                                            anchor="w",
                                            variable=self.file_name)
        folder_select.place(x=185, y=40, width=100, height=20)

        folder_select = tkinter.Checkbutton(self.root,
                                            text="文件内容",
                                            anchor="w",
                                            variable=self.file_content)
        folder_select.place(x=290, y=40, width=100, height=20)

        #字符串
        tkinter.Label(self.root,
                      font=("宋体", 10),
                      fg="blue",
                      anchor="w",
                      text="原字符串").place(x=5, y=70, width=70, height=20)
        source_text = tkinter.Entry(self.root,
                                    textvariable=self.string_old)
        source_text.place(x=80, y=70, width=310, height=20)

        tkinter.Label(self.root,
                      font=("宋体", 10),
                      fg="blue",
                      anchor="w",
                      text="新字符串").place(x=5, y=100, width=70, height=20)
        source_text = tkinter.Entry(self.root,
                                    textvariable=self.string_new)
        source_text.place(x=80, y=100, width=310, height=20)

        # 开始修改
        button_start = tkinter.Button(self.root,
                                      font=("宋体", 12),
                                      text="开始修改",
                                      command=self.start)
        button_start.place(x=165, y=130, width=70, height=30)

    def matchcase(self, word):
        return word
        # def rmodify(m):
        #     # re.sub会将匹配到的对象,循环调用modify方法传入
        #
        #     # 获取匹配的文本
        #     text = m.group()
        #
        #     if text.isupper():
        #         # 如果文本全部是大写,就返回word的全部大写模式
        #         return word.upper()
        #     elif text.islower():
        #         # 如果文本全部是小写,就返回word的全部小写模式
        #         return word.lower()
        #     elif len(text) > 0 and text[0].isupper():
        #         # 如果文本是首字母大写,就返回word的首字母大写模式
        #         return word.capitalize()
        #     else:
        #         # 其他情况,直接返回word
        #         return word
        #
        # return modify

    def modify(self, path):
        # 修改当前文件夹名称
        if self.folder_name.get() == 1:
            folder = os.path.basename(path)
            folder = re.sub(self.string_old.get(),
                            self.matchcase(self.string_new.get()),
                            # flags=re.IGNORECASE,
                            folder)
            os.rename(path, os.path.join(os.path.dirname(path), folder))
            path = os.path.join(os.path.dirname(path), folder)

        filenames = os.listdir(path)
        logger.info(f"file list {filenames}")

        for filename in filenames:
            domain = os.path.abspath(path)
            file_path = os.path.join(domain, filename)

            # 递归修改子文件名称、文件名称、文件内容
            if os.path.isdir(file_path):
                if self.folder_name.get() == 1:
                    filename = re.sub(self.string_old.get(),
                                      self.matchcase(self.string_new.get()),
                                      # flags=re.IGNORECASE,
                                      filename)
                    os.rename(file_path, os.path.join(domain, filename))
                    file_path = os.path.join(domain, filename)

                logger.debug(f"enter folder {file_path}")
                self.modify(file_path)
                logger.debug(f"exit folder {file_path}\n")
                continue

            # 修改文件名称
            if self.file_name.get() == 1:
                filename = re.sub(self.string_old.get(),
                                 self.matchcase(self.string_new.get()),
                                  # flags=re.IGNORECASE,
                                 filename)
                os.rename(file_path, os.path.join(domain, filename))
                file_path = os.path.join(domain, filename)

            # 修改文件内容
            if self.file_content.get() == 1:
                format = file_path.split(".")[-1]
                if format != "c" and format != "h" and format != "txt":
                    logger.info(f"can not process {file_path}")
                    continue;

                fread = open(file_path, 'r')
                fwrite = open("%s.backup" % file_path, 'w')

                while True:
                    line = fread.readline()
                    if len(line) > 0:
                        line = re.sub(self.string_old.get(),
                                      self.matchcase(self.string_new.get()),
                                      # flags=re.IGNORECASE,
                                      line)
                        fwrite.write(line)
                    else:
                        break
                fread.close()
                fwrite.close()
                os.remove(file_path)
                os.rename("%s.backup" % file_path, file_path)

    def start(self):
        if self.path.get() == "":
            tkinter.messagebox.showinfo('错误', "请选择文件夹路径!")
        else:
            logger.info(f'''路径:"{self.path.get()}"''')
            logger.info("修改选项:")
            option_count = 0
            if self.folder_name.get() == 1:
                option_count = option_count + 1
                logger.info(f"  {option_count}. 文件夹名称")
            if self.file_name.get() == 1:
                option_count = option_count + 1
                logger.info(f"  {option_count}. 文件名称")
            if self.file_content.get() == 1:
                option_count = option_count + 1
                logger.info(f"  {option_count}. 文件内容")
            logger.info(f"原字符串:{self.string_old.get()}")
            logger.info(f"新字符串:{self.string_new.get()}")
            self.modify(self.path.get())
            tkinter.messagebox.showinfo('结果', "修改完成")

    def log(self):
        os.startfile("log.txt")
        # domain = os.path.abspath(os.getcwd())
        # log_path = os.path.join(domain, "log")
        #
        # log = open(log_path, 'r')
        # log.close()

    def rule(self):
        tkinter.messagebox.showinfo('批量修改字符串规则',
                                    "1.修改当前文件夹及子文件夹的名称;\n"
                                    "2.修改当前文件夹及子文件夹下所有文件的名称;\n"
                                    "3.修改当前文件夹及子文件夹下所有文件的内容;\n")

    def about(self):
        tkinter.messagebox.showinfo('批量修改字符串',
                                    "作者:Risun_Lee\n"
                                    "版本: V1.0\n"
                                    "发布日期: 2020年9月8日\n")

    def release_note(self):
        tkinter.messagebox.showinfo('版本说明',
                                    "V1.0:\n"
                                    "1.支持文件夹名称、文件名称的修改;\n"
                                    "2.支持txt、c、h文件内容的修改;\n")

    def select_path(self):
        path = tkinter.Tk()
        path.withdraw()
        fpath = os.path.normpath(tkinter.filedialog.askdirectory())
        if fpath != ".":
            self.path.set(str(fpath))

def main():
    create_logger(level=logging.DEBUG)
    modify_string()

if __name__ == '__main__':
    main()

Guess you like

Origin blog.csdn.net/Allure_LoveU/article/details/120947623