Python 删除内容相同,名称不同的图片,查找固定格式内容,修改SVG文件的图片链接,保存文件。

本篇文章记录学习:

一、实现功能

1.image文件去重

1)将image文件里有上千张图片,其中大部分图片是内容相同,但是名称不同的文件。
2)去重原则是通过计算每张图片md5,md5值相同,则表示内容相同,则可以删除。

  • 以字典方式保存第一张图片得md5值(value)和图片名称(key)
  • 以字典方式保存删除图片名称(key)和已存MD5 对应的图片名称(value)

备注:保存删除图片名称得意义:将SVG文件调用删除图片的连接名称修改为第一张图片的名称。。

在这里插入图片描述

2.查找其他文件里包含“删除图片”的字符串

在这里插入图片描述

在这里插入图片描述

  • 通过正则表达式,逐一打开所在目录的svg文件,逐行查找,根据正则表达式规则查中找是否有匹配的图片名称的字符串,
  • 如果有匹配的图片名称字符串,判断字符串是否在all_svg_jpg字典中
  • 如果在,则进行替换,如果不在,则进行源文件内容打印
# coding=UTF-8
import re
import hashlib
import os
import time
import logging
import logging.handlers

LOG_FILE = 'svg_parser.log'

handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes=1024 * 1024, backupCount=5)  # 实例化handler
fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s'

formatter = logging.Formatter(fmt)  # 实例化formatter
handler.setFormatter(formatter)  # 为handler添加formatter

logger = logging.getLogger('svg_parser')  # 获取名为tst的logger
logger.addHandler(handler)  # 为logger添加handler
logger.setLevel(logging.DEBUG)


def getmd5(filename):
    """
    获取文件 md5 码
    :param  filename: 文件路径
    :return: 文件 md5 码
    """
    file_txt = open(filename, 'rb').read()
    # 调用一个md5对象
    m = hashlib.md5(file_txt)
    # hexdigest()方法来获取摘要(加密结果)
    return m.hexdigest()


def getallkey(path):
    """
        1.将image文件夹里数据通过md5 码判断是否是相同内容不同名字的文件,如果是则保留第一次遇到的文件名及md5.
        2.将1对多图片(重复的图片名称和需要替换的图片名称)保存在all_svg_jpg字典:
            all_svg_jpg的key为将在SVG文件里查找到的图片名称
            all_svg_jpg的value将SVG文件里查找到的图片名称替换的新名称
        :param  path: 程序所在路径,也就是svg所在路径,与image文件夹级别相同
        :return: 空
        """
    # 文件夹路径
    # path = input("path: ")
    image_path = path + "\image"
    # 存放文件的 md5 码
    all_svg = {}  # 改为字典
    global all_svg_jpg
    all_svg_jpg = {}  # 存储所有svg里面的链接的jpg、gif 与image下的jpg、gif对应值。

    total_save = 0
    total_file = 0
    total_delete = 0

    # 开始时间
    # start = time.time()
    # 遍历文件夹下的所有文件
    for file in os.listdir(image_path):
        # 文件数量加 1
        total_file += 1
        # 文件的路径
        # real_path = os.path.join(path, file)
        real_path = image_path + "\\" + file
        filename = os.path.split(real_path)[1]
        # 获取image文件的md5码
        filemd5 = getmd5(real_path)
        # 如果文件 md5 已存在,则删除此文件
        if filemd5 in all_svg.values():  # 字典的值为已存在的文件 md5 码
            total_delete += 1
            for svgnamekey, svgmd5value in all_svg.items():
                if svgmd5value == filemd5:
                    # print(f"svgnamekey= {svgnamekey}  svgmd5value = {svgmd5value} filename :{filename}")
                    all_svg_jpg[filename] = svgnamekey
                    os.remove(real_path)
                    # print('删除', real_path)
        else:
            # 如果文件 md5 不存在,则将此文件的 md5 码添加到 all_svg 字典中,文件名为key,文件value为md5
            all_svg[filename] = filemd5

    # 结束时间
    # end = time.time()
    # time_last = end - start
    # for key, value in all_svg_jpg.items():
    #     # print(f"key= {key}  value = {value}")
    #     total_save += 1
    print('image文件总数:', total_file)
    print('删除image个数:', total_delete)
    logger.info(f'image文件总数:{total_file}')
    logger.info(f'删除image个数:{total_delete}')
    # print('耗时:', time_last, '秒')
    # print('存储键值对个数:', total_save)


def alter(file):
    """
       1.逐一打开所在目录的svg文件,逐行查找,根据正则表达式规则查中找是否有匹配的图片名称的字符串,
       2.如果有匹配的图片名称字符串,判断字符串是否在all_svg_jpg字典中
       3.如果在,则进行替换,如果不在,则进行源文件内容打印


        :param  file: svg所在路径
        :return: bFind   False:没修改文件 True:成功修改文件
        """
    bFind = False
    with open(file, "r", encoding="utf-8") as f1, open("%s.bak" % file, "w", encoding="utf-8") as f2:
        for line in f1:
            search_obj = re.search(
                "image/([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}.(jpg|gif|png))",
                line)
            if search_obj:
                # 在svg文件中找到匹配的图片,判断该图片是否在all_svg_jpg字典中,如果在,则进行替换,修改SVG文件并保存
                for key, value in all_svg_jpg.items():
                    if key == search_obj.group(1):
                        print(f"file :{file}  旧字符串= {search_obj.group(1)}  新字符串 = {value}")
                        logger.info(f"file :{file}  旧字符串= {search_obj.group(1)}  新字符串 = {value}")
                        # 修改SVG
                        f2.write(re.sub(search_obj.group(1), value, line))
                        bFind = True

            else:
                f2.write(line)

    os.remove(file)
    os.rename("%s.bak" % file, file)

    return bFind


def filepath():
    global path
    path = os.getcwd()  # 获取指定路径下的文件
    dirs = os.listdir(path)
    # 准备要替换的数据
    # print(path)
    getallkey(path)
    total_file = 0
    total_right = 0
    total_wrong = 0

    for svgname in dirs:  # 循环读取路径下的文件并筛选输出
        if os.path.splitext(svgname)[1] == ".svg":  # 筛选svg文件
            # print(svgname)

            num = alter(svgname)
            total_file += 1
            if num > 0:
                total_right += 1
            else:
                total_wrong += 1
    print('SVG文件总数:', total_file)
    print('修改SVG个数:', total_right)
    print('未修SVG改个数:', total_wrong)
    logger.info(f'SVG文件总数:{total_file}')
    logger.info(f'修改SVG个数:{total_right}')
    logger.info(f'未修SVG改个数:{total_wrong}')


if __name__ == '__main__':
    filepath()
    time.sleep(60)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值