• 文件内容差异对比 摩天居士


    示例1:difflib模块——两个字符串的差异对比

      通过使用difflib模块实现两个字符串的差异对比,然后以版本控制风格进行输出。

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 import difflib
     5 
     6 text1 = '''test1:             #字符串1
     7 This module provides classes.
     8 including HTML and context.
     9 difflib document7.4
    10 add string
    11 '''
    12 text1_lines = text1.splitlines()   #以行进行分隔
    13 
    14 text2 = '''test2:             #字符串2
    15 This module provides classes.
    16 including HTML and context.
    17 difflib document7.5
    18 '''
    19 
    20 text2_lines = text2.splitlines()
    21 
    22 d = difflib.Differ()         #创建Differ()对象
    23 
    24 diff = d.compare(text1_lines,text2_lines)       采用compare方法对字符串进行比较
    25 print('\n'.join(list(diff)))
    View Code

      可以将以上代码换行html格式,将如上脚本运行python diff.py > diff.html,在使用浏览器打开diff.html文件

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 import difflib
     5 
     6 text1 = '''test1:             #字符串1
     7 This module provides classes.
     8 including HTML and context.
     9 difflib document7.4
    10 add string
    11 '''
    12 text1_lines = text1.splitlines()   #以行进行分隔
    13 
    14 text2 = '''test2:             #字符串2
    15 This module provides classes.
    16 including HTML and context.
    17 difflib document7.5
    18 '''
    19 
    20 text2_lines = text2.splitlines()
    21 
    22 # d = difflib.Differ()         #创建Differ()对象
    23 #
    24 # diff = d.compare(text1_lines,text2_lines)       采用compare方法对字符串进行比较
    25 # print('\n'.join(list(diff)))
    26 
    27 d = difflib.HtmlDiff()
    28 print(d.make_file(text1_lines,text2_lines))
    View Code

    示例2:difflib模块——对比nginx配置文件

      当我们维护多个Nginx配置时,时常会对比不同版本配置文件的差异,使运维人员更加清晰的了解不同版本迭代后的更新项,实现的思路是读取两个需对比的配置文件,再以换行符作为分隔符,调用difflib.HtmlDiff()生成HTML格式的差异文档。

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 
     5 
     6 import difflib
     7 import sys
     8 
     9 #首先判断脚本是否传了正确参数
    10 
    11 try:
    12     textfile1 = sys.argv[1]
    13     textfile2 = sys.argv[2]
    14 except Exception as e:
    15     print("Error" + str(e))
    16     print("Usage: simple3.py filename1 filename2")
    17     sys.exit()
    18 
    19 #定义一个读取文件的函数,以换行符进行分隔
    20 def readfile(filename):
    21     try:
    22         with open(filename,'rb') as fin:
    23             text = fin.read().splitlines()
    24             return text
    25     except IOError as error:
    26         print("Read file Error:" + str(error))
    27         sys.exit()
    28 
    29 text1_lines = readfile(textfile1)
    30 text2_lines = readfile(textfile2)
    31 
    32 d = difflib.HtmlDiff()
    33 print(d.make_file(text1_lines,text2_lines))
    View Code

        运行代码: 

    # python simple3.py nginx.v1.conf nginx.v2.conf > diff.html

    示例三:filecmp模块——文件与目录差异对比

      模块常用方法说明:fileemp提供了三个操作方法,分别为cmp(单文件对比)、cmpfile(多文件对比)、dircmp(目录对比),下面逐一进行介绍:

    •  单文件对比,采用filecmp.cmp (f1,f2[,shallow])方法,比较文件名为f1和f2的文件,相同返回True,不相同返回False,shallow默认为True。
    •  多文件对比,采用filecmp.cmpfiles(dir1,dir2,common[,shallow])方法,对比dir1与dir2目录给定的文件清单。该方法返回文件名的三个列表,分别为匹配,不匹配,错误。匹配为包含匹配的文件的列表,不匹配反之,错误列表包括了目录不存在的文件、不具备读权限或其他原因导致的不能比较的文件清单。
    • 目录对比,采用filecmp.dircmp(a,b[,ignore[,hide]])类创建一个目录比较对象,其中a和b是参加比较的目录名。ignore代表文件名忽略的列表,并默认为['RCS','CVS','tags'];hide代表隐藏的列表,默认为[os.curdir(当前目录),os.pardir(上一层目录)],dircmp类可以获得目录比较的详细信息,如只有在a目录中包括的文件、a与b都存在的子目录、匹配的文件等,同时支持递归。

    示例四:校验源与备份目录差异

      有时候我们无法确认备份目录与源目录文件是否一致,包括源目录中的新文件或目录、更新文件或目录有无成功同步,定期进行校验,没有成功则希望有针对性地进行补备份。

      如下示例使用了filecmp模块的left_only、diff_files方法递归获取源目录的更新项,在通过shutil.copyfile、os.makedirs方法对更新项进行复制,最终保持一致状态。代码如下:

     1 #!/usr/bin/evn python
     2 # --*-- coding: utf-8 --*--
     3 # Auther : Liu WeiDong
     4 
     5 import os,sys
     6 import filecmp
     7 import re
     8 import shutil
     9 
    10 holderlist = []
    11 
    12 # 定义一个函数,判断两个目录差异
    13 def compareme(dir1,dir2):
    14     dircomp = filecmp.dircmp(dir1,dir2)
    15     only_in_leftdir = dircomp.left_only    #返回一个只在dir1中的文件或目录列表
    16     diff_in_leftdir = dircomp.diff_files   #显示返回两个目录中相同文件名,内容不同
    17     #dirpath = os.path.abspath(dir1)       # 定义源文件的绝对路径
    18 
    19     #将更新的文件名或目录追加到holderlist
    20     for i in only_in_leftdir:
    21         holderlist.append(os.path.abspath(os.path.join(dir1,i)))
    22 
    23     for i in diff_in_leftdir:
    24         holderlist.append(os.path.abspath(os.path.join(dir1,i)))
    25 
    26     #判断是否存在相同子目录,以便递归
    27     if len(dircomp.common_dirs) > 0:
    28         for i in dircomp.common_dirs:
    29             compareme(os.path.abspath(os.path.join(dir1,i)),os.path.abspath(os.path.join(dir2,i)))
    30         return holderlist
    31 
    32 def main():
    33     if len(sys.argv) > 2:   #判断脚本参数个数是否大于2
    34         dir1 = sys.argv[1]
    35         dir2 = sys.argv[2]
    36     else:
    37         print("Usage: ",sys.argv[0]," datadir backupdir")
    38         sys.exit()
    39 
    40     #调用compareme函数,对传入的两个目录进行对比
    41     different_file = compareme(dir1,dir2)
    42     dir1 = os.path.abspath(dir1)
    43 
    44     if not dir2.endswith("/"):
    45         dir2 = dir2 + '/'
    46         dir2 = os.path.abspath(dir2)
    47         destination_files = []
    48         creatdir_bool = False
    49 
    50     for item in different_file:  #遍历返回的差异文件或目录列表
    51         destination_dir = re.sub(dir1,dir2,item)  #将源目录差异路径清单对应替换成备份目录
    52         destination_files.append(destination_dir) # 备份目录内容更新到定义的destination_files列表中
    53         if os.path.isdir(item):       # 如果差异路径为目录且不存在,则在备份目录中创建
    54             if not os.path.exists(destination_dir):
    55                 os.makedirs(destination_dir)
    56                 creatdir_bool = True
    57 
    58     if creatdir_bool:   #重新调用compareme函数,重新遍历创建目录的内容
    59         destination_files = []
    60         different_file = []
    61         different_file = compareme(dir1,dir2)
    62         for item in different_file:
    63             destination_dir = re.sub(dir1,dir2,item)
    64             destination_files.append(destination_dir)
    65 
    66     print("update item:")
    67     print(destination_files)
    68     copy_pair = zip(different_file,destination_files)
    69     for item in copy_pair:
    70         if os.path.isfile(item[0]):
    71             shutil.copyfile(item[0],item[1])
    72 
    73 if __name__ == '__main__':
    74     main()
    View Code
  • 相关阅读:
    [osg][原]自定义osgGA漫游器
    [osg]osg窗口显示和单屏幕显示
    sql中去除重复的数据 select distinct * from table
    Microsoft VBScript 运行时错误 错误 800a005e 无效使用 Null: Replace
    如何解决Access操作或事件已被禁用模式阻止
    sql 中 '' 与 null 的区别
    IsNull、rs、sum
    Access与SQL中的IsNull(),IS NULL的区别
    ASP将Table导出Excel
    ASP如何将table导出EXCEL表格
  • 原文地址:https://www.cnblogs.com/weidongliu/p/16442338.html
Copyright © 2020-2023  润新知