2.1 文件内容差异对比方法

news2025/1/9 14:49:30

2.1 文件内容差异对比方法

    • 文件内容差异对比方法
      • 2.1.1 两个字符串的差异对比
      • 2.1.2 生成美观的HTML格式文档
      • 2.1.3 对比nginx 配置文件差异
      • 代码封装

文件内容差异对比方法

介绍如何通过difflib模块实现文件内容差异对比。difflib作为Python的标准库模块无需安装,作用是对比文本之间的差异,且支持输出可读性比较强的HTML文档,与Linux下的 diff命令相似。我们可以使用difflib 对比代码、配置文件的差别,在版本控制方面是非常有用。

在这里插入图片描述

2.1.1 两个字符串的差异对比

  1. 传递文件内容,然后进行简单的行切割
  2. 创建differ函数
  3. 在differ对象的基础上,借助于compare方法将两个内容进行对比
  4. 结果以join的方式展示
import difflib

# 准备第一个文件
text1 = """text1:
This module provides classes and functions for comparing 
includes
add string
"""
# 准备第二个文件
text1_line = text1.splitlines()     # 以行进行分割,以便进行对比
text2 = """text2:
This module provides classes and functions for comparing 
includes add string
"""
text2_line = text2.splitlines()
# 创建differ对象
d = difflib.Differ() #创建Differ对象
# 使用compare方法比较内容
diff = d.compare(text2_line,text1_line)
print(diff)
#<generator object Differ.compare at 0x000002249D0A7C80>

# 拼接比较后的结果
print('\n'.join(list(diff)))
<generator object Differ.compare at 0x0000024ABEC97C10>
- text2:
?     ^

+ text1:
?     ^

  This module provides classes and functions for comparing 
- includes add string
+ includes
+ add string

在这里插入图片描述

2.1.2 生成美观的HTML格式文档

采用 HtmIDiff()类的 make_file() 方法就可以生成美观的HTML文档

HtmlDiff() 类的make_file()方法:生成美观的HTML文档

  1. 传递文件内容,然后进行简单的行切割
  2. 创建HtmlDiff函数
  3. 在HtmlDiff对象的基础上,借助于make_file()方法将两个内容进行对比
  4. 直接查看生成的文件
    效果:
    颜色
    统计
import difflib

# 准备第一个文件
text1 = """text1:
This module provides classes and functions for comparing 
includes
add string
"""
# 准备第二个文件
text1_line = text1.splitlines()     # 以行进行分割,以便进行对比
text2 = """text2:
This module provides classes and functions for comparing 
includes add string
"""
text2_line = text2.splitlines()
# 创建differ对象
d = difflib.HtmlDiff() #创建Differ对象
# 使用compare方法比较内容
diff = d.make_file(text2_line,text1_line)
# 将输出的对比效果放到一个文件中 --with open 方法
with open('diff.html','w') as f:
    f.write(diff)

在这里插入图片描述

2.1.3 对比nginx 配置文件差异

  1. 准备两个nginx文件
  2. 分别读取两个配置文件
  3. 读取内容
  4. 文件内容的基本判断
  5. 内容的比较
  6. 结果的输出
import difflib
import sys

# 1. 准备文件
# 格式: python pythonauto_30_文件对比-配置实践.py nginx.conf1  nginx.conf2
# 2. 读取文件
# argv -- 命令行;argv[0]脚本名,agrv[1]是第一个参数,依次类推
try:
    textfile1 = sys.argv[1]
    textfile2 = sys.argv[2]
    
# 如果在尝试读取命令行参数时发生了异常(例如,没有提供足够的参数),
# 则会捕获这个异常,并执行except块中的代码。
except Exception as e:
    # str(e)将异常对象e转换为字符串,以便打印。
    print(f"Error: str({e})")
    print("Usage: diff-file.py filename1 filename2")
    sys.exit()
    
# 3.读取内容
def readfile(filename):
    try:
        with open(filename,'r') as f:
            text = f.read().splitlines()	#读取后以行进行分隔
            return text
    except Exception as error:
        print("读取文件错误:{}".format(error))
        sys.exit()

# 4. 文件内容为空的基本判断
if textfile1 == "" or  textfile2 == "":
    print("脚本的参数不允许为空,请检查")
    print(f"Usage: diff-file.py filename1 filename2")
    sys.exit()
# 5. 内容的比较
# 5.1读取文件
text1_line = readfile(textfile1)
text2_line = readfile(textfile2)
# 5.2 创建Htmldiff对象
diff_object = difflib.HtmlDiff()
# 5.3 对文件进行比较
diff_result = diff_object.make_file(text1_line,text2_line)

# 6.输出结果
with open('nginx_diff.html','w') as f:
    f.write(diff_result)

代码封装

定义了一个名为 DiffContent 的类,该类提供了两个主要功能:

  1. 比较两个文件的内容差异,并将差异结果保存为 HTML 文件;
  2. 以及比较两个字符串(文本)的差异,并同样将差异结果保存为 HTML 文件。
import difflib
import os.path
import time
from typing import List

class DiffContent:

    @classmethod
    def _read_file(cls, file_path: str) -> List[str]:
        """
        读取指定路径的文件内容,并将其作为字符串列表返回,每个列表项代表文件的一行
        :param file_path: 文件绝对路径
        :return: 列表,包含文件的所有行
        """
        try:
            with open(file_path, "rb") as f:
                # 二进制方式读取文件内容,并转换为str类型
                lines = f.read().decode('utf-8')
                # 按行进行分割
                text = lines.splitlines()
                return text
        except Exception as e:
            print("ERROR: {}".format(str(e)))
            return []  # 返回空列表以避免后续错误  

    @classmethod
    def compare_diff_by_file(cls, file1: str, file2: str, save_path: str = '') -> None:
        """
        对比文件内容差异,并输出html文件,文件名命名:compare_file1name_file2name.html
        :param file_1:文件1
        :param file_2:文件2
        :param save_path:如果未指定,则在当前目录下保存文件
        :return:
        """
        # 获取文件内容
        file1_content = cls._read_file(file1)
        file2_content = cls._read_file(file2)
        # 创建比较器
        compare = difflib.HtmlDiff()
        res = compare.make_file(file1_content, file2_content)
        # 获取输出html文件的绝对路径
        file1_name = os.path.basename(file_1).split('.')[0]
        file2_name = os.path.basename(file_2).split('.')[0]
        if not file_1_name or not file_2_name:  
            raise ValueError("File names must contain an extension to generate a valid output file name.")  
        if save_path:
            out_file = '{}/compare_{}_{}.html'.format(save_path, file_1_name, file_2_name)
        else:
            out_file = 'compare_{}_{}.html'.format(file_1_name, file_2_name)
        with open(out_file, 'w') as f:
            f.writelines(res)

    @classmethod
    def compare_text(cls, src_text: str, target_text: str, save_path: str = '') -> None:
        """
        比较给定的2个字符串,并输出html文件
        :param src_text:
        :param target_text:
        :param save_path:如果未指定,则在当前目录下保存文件
        :return:
        """
        compare = difflib.HtmlDiff()
        compare_result = compare.make_file(src_text, target_text)
        if save_path:
            out_file = f"{save_path}/compare{int(time.time())}.html"  # 使用整数时间戳避免微秒差异  
        else:
            out_file = 'compare{}.html'.format(str(time.time()).split('.')[0])
        with open(out_file, 'w') as f:
            f.writelines(compare_result)

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

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

相关文章

算法学习——树形DP——多叉树的最长路径

文章目录 引言正文0、题目的具体内容1、树的直径定理推导3、使用数组链表表示树使用数组表示链表数组表示单链表头插法演示数组表示单链表在索引k出插入一个数字数组表示链表实现代码链表表示树 4、树形DP的具体分析 总结 引言 这个问题&#xff0c;每一次都会痛击我&#xff…

养猫劝退?猫咪掉毛严重怎么办?用宠物空气净化器高效清理浮毛

不瞒大家说&#xff0c;养猫以来&#xff0c;我中途有无数次想要把它送人的想法&#xff0c;最终还是敌不过它的可爱留下来了。为什么会产生这样的念头呢&#xff1f;罪魁祸首就是猫毛问题。夏天是猫咪的换毛季&#xff0c;它们为了散热会脱去厚重的毛发&#xff0c;进入疯狂掉…

06结构型设计模式——代理模式

一、代理模式简介 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff08;GoF书中解释结构型设计模式&#xff1a;一种用来处理类或对象、模块的组合关系的模式&#xff09;&#xff0c;代理模式是其中的一种&#xff0c;它可以为其他对象提供一种代…

依赖倒置原则详解

依赖倒置原则详解 一、引言 在大型系统架构设计中&#xff0c;依赖倒置原则&#xff08;Dependency Inversion Principle&#xff0c;DIP&#xff09;被广泛视为增强系统灵活性和可维护性的核心原则之一。最近在架构设计审查中&#xff0c;我们经常遇到由于依赖关系设计不当导…

叠Buff!经典麻雀优化算法+多重双向深度学习!SSA-BiTCN-BiGRU-Attention多输入单输出回归预测

叠Buff!经典麻雀优化算法多重双向深度学习&#xff01;SSA-BiTCN-BiGRU-Attention多输入单输出回归预测 目录 叠Buff!经典麻雀优化算法多重双向深度学习&#xff01;SSA-BiTCN-BiGRU-Attention多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matl…

P2858 [USACO06FEB] Treats for the Cows

题目描述 约翰经常给产奶量高的奶牛发特殊津贴&#xff0c;于是很快奶牛们拥有了大笔不知该怎么花的钱。为此&#xff0c;约翰购置了 N 份美味的零食来卖给奶牛们。每天约翰售出一份零食。当然约翰希望这些零食全部售出后能得到最大的收益。这些零食有以下这些有趣的特性&…

(python)动态类型语言的灵活性和动态性

前言 一种具有动态类型,动态绑定&#xff0c;动态执行和灵活的对象模型的编程语言。它能够适应不断变化的编程需求的&#xff0c;是否会受欢迎? 动态语言的优点 灵活性高&#xff1a;开发过程更加灵活和快捷&#xff0c;不需要在编写代码前严格定义变量和对象的类型&#xff0…

linux之prometheus+grafana

Prometheus介绍 Prometheus(普罗米修斯)是一套开源的监控&报警&时间序列数据库的组合, 由go语言开发。 适合监控容器平台, 因为kubernetes(俗称k8s)的流行带动了prometheus的发展。 PS&#xff1a;由于目前还未学习容器&#xff0c;所以在今天的课程里使用prometheus监…

嵌入式Linux:proc文件系统

目录 1、使用 cat 命令读取 /proc 文件系统 2、在应用程序中使用 open() 和 read() 函数读取 /proc 文件系统 proc 文件系统是一个虚拟文件系统&#xff0c;它以文件系统的形式为应用层提供访问系统内核数据的接口。用户和应用程序可以通过 proc 文件系统获取系统信息和进程相…

腾讯一面算法题:最长重复子串 1044,讲个比较好理解的思路

文章目录 1044. 最长重复子串前言思路Version 1&#xff1a;暴力Version 2&#xff1a;引入二分&#xff0c;优化 O ( n 2 ) O(n^2) O(n2)Version 3&#xff1a;引入自定义哈希&#xff0c;优化字符串比较Version 4&#xff1a;计算所有字符串的哈希值Version 5&#xff1a;引…

前后端项目交互异步请求JSON数据类型后端标准响应数据格式

java同步请求 当网页与后端交互时,前端不能再进行其他操作 服务器响应回来的内容,会把整个浏览器中的内容覆盖 这种请求方式在前后端交互时不太友好 现在的前后端交互请求都使用异步请求 异步请求(不同步) 通过在前端中使用js中提供的XMLHttpRequest对象实现发送异步请求…

人工智能与机器学习在医学领域的应用

作者主页: 知孤云出岫 人工智能与机器学习在医学中的应用 目录 作者主页:人工智能与机器学习在医学中的应用1. 引言2. 医学中的AI和ML技术概述2.1 人工智能和机器学习基础2.2 数据在医学AI中的重要性 3. 医学AI和ML的具体应用领域3.1 影像诊断3.2 基因组学与个性化医疗3.3 疾…

JavaEE篇:多线程(1)

一 认识线程(Thread) 1.1 概念 1.1.1 线程是什么&#xff1f; 线程被创建出来是为了完成分配给它的任务。线程又称轻量级进程&#xff0c;是操作系统的基本调度单位。一个线程就是一个执行流。线程的创建销毁和切换都比进程更加的方便。进程是操作系统分配资源的基本单位&am…

C++ //练习 17.16 如果前一题程序中的regex对象用“[^c]ei“进行初始化,将会发生什么?用此模式测试你的程序,检查你的答案是否正确。

C Primer&#xff08;第5版&#xff09; 练习 17.16 练习 17.16 如果前一题程序中的regex对象用"[^c]ei"进行初始化&#xff0c;将会发生什么&#xff1f;用此模式测试你的程序&#xff0c;检查你的答案是否正确。 环境&#xff1a;Linux Ubuntu&#xff08;云服务…

「C++系列」数据结构

文章目录 一、数据结构1. 线性数据结构2. 非线性数据结构3. 其他重要数据结构 二、定义数据结构1. 数组&#xff08;Array&#xff09;2. 链表&#xff08;LinkedList&#xff09;3. 栈&#xff08;Stack&#xff09; 三、指针、关键字1. 指针链表树 2. 关键字 四、相关链接 一…

【TCP/IP】UDP协议数据格式和报文格式

学习一个网络协议&#xff0c;主要就是学习“数据格式”/“报文格式” 源端口/目的端口 端口号是属于传输层的概念UDP 报头使用两个自己的长度来表示端口号之所以端口号的范围是 0~65535&#xff0c;是因为底层网络协议做出了强制要求如果使用一个 10 w 这样的端口&#xff0…

机器学习:多元线性回归模型

目录 前言 一、讲在前面 1.多元_血压.csv&#xff1a; 2.完整代码&#xff1a; 3.运行结果&#xff1a; 二、实现步骤 1.导入库 2.导入数据 3.绘制散点图&#xff08;这步可以省略&#xff09; ​编辑 4.求特征和标签的相关系数 5.建立并训练线性回归模型 6.检验模…

NtripShare全站仪自动化监测之气象改正

最近有幸和自动化监测领域权威专家进行交流&#xff0c;讨论到全站仪气象改正的问题&#xff0c;因为有些观点与专家不太一致&#xff0c;所以再次温习了一下全站仪气象改正的技术细节。 气象改正的概念 全站仪一般利用光波进行测距&#xff0c;首先仪器会处理测距光波的相位漂…

C++| QT图片调整透明度叠加

QT图片调整透明度叠加 实际效果界面UI放置控件设置布局界面自适应 代码项目工程的文件初始化按钮功能滑动条功能图片调整透明度叠加 实际效果 三个图片&#xff08;QLabel&#xff09;显示&#xff0c;两个按钮&#xff08;QPushButton&#xff09;加载图片&#xff0c;一个&a…

【Java学习】反射和枚举详解

所属专栏&#xff1a;Java学习 &#x1f341;1. 反射 在程序运行时&#xff0c;可以动态地创建对象、调用方法、访问和修改字段&#xff0c;以及获取类的各种属性信息&#xff08;如成员变量、方法、构造函数等&#xff09;&#xff0c;这种机制就称为反射 反射相关的类 类名用…