• 文件内容差异比对--difflib、filecmp


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

    1、两个字符串的差异对比

     1 #!/usr/bin/env python
     2 #coding=utf-8
     3 import difflib
     4 
     5 #比对两个字符串中的不同点
     6 text1 = "text1 hello world!"   #定义字符串
     7 text1_lines = text1.splitlines()  #进行分隔,以便进行对比
     8 text2 = "text2 Hello World."
     9 text2_lines = text2.splitlines()
    10 
    11 a = difflib.Differ()  #创建Differ()对象
    12 diff = a.compare(text1_lines,text2_lines)  #采用compare方法对字符串进行比较
    13 print '
    '.join(list(diff)) 

     

    实践对比Nginx配置文件差异

     1 #!/usr/bin/env python
     2 #coding=utf-8
     3 
     4 import difflib
     5 import sys
     6 try:
     7     textfile1 = sys.argv[1]  #第一个配置文件路径参数
     8     textfile2 = sys.argv[2]  #第二个配置文件路径参数
     9 
    10 except Exception,e:     
    11     print "Error:" + str(e)
    12     print "Usage: file_diff.py filename1 filename2"
    13     sys.exit()
    14 
    15 def readfile(filename):    #文件读取分隔函数
    16     try:
    17         fileHandle = open (filename, 'rb')
    18         text = fileHandle.read().splitlines()  #读取以后进行分隔
    19         fileHandle.close()
    20         return text
    21     except IOError as error:
    22         print ('Read file Error:' + str(error))
    23         sys.exit()
    24 
    25 if textfile1 == "" or textfile2 == "":
    26     print "Usage: file_diff.py filename1 filename2"
    27     sys.exit()
    28 
    29 text1_lines = readfile(textfile1)  #调用readfile函数,获取分隔后的字符串
    30 text2_lines = readfile(textfile2)
    31 
    32 d = difflib.HtmlDiff()   #创建HtmlDiff()类对象
    33 print d.make_file(text1_lines,text2_lines)  #通过make_file方法输出HTML格式的对比结果
    34 
    35 运行如下代码:
    36 python sample.py nginx.conf.v1 nginx.conf.v2 > diff.html

    2、文件与目录差异对比方法

    filecmp提供了三个操作方法,分别是cmp(单文件对比)、cmpfiles(多文件对比)、dircmp(目录对比)

     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     3 
     4 import os, sys
     5 import filecmp
     6 import re
     7 import shutil
     8 
     9 holderlist = []
    10 
    11 ##对应第一个步骤
    12 def compare_me(dir1, dir2):   #递归获取更新项函数
    13     dircomp = filecmp.dircmp(dir1, dir2)
    14     only_in_one = dircomp.left_only   #源目录新文件或目录
    15     diff_in_one = dircomp.diff_files  #不匹配文件,源目录已发生变化
    16     dirpath = os.path.abspath(dir1)   #定义源目录绝对路径
    17 
    18     #将更新文件名或者目录追加到holderlist
    19     [ holderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in only_in_one ]
    20     [ holderlist.append(os.path.abspath(os.path.join(dir1, x))) for x in diff_in_one ]
    21     if len(dircomp.common_dirs) > 0:
    22         for item in dircomp.common_dirs:
    23             compare_me(os.path.abspath(os.path.join(dir1, item)), os.path.abspath(os.path.join(dir2, item)))
    24     return holderlist
    25 
    26 ##对应第二个步骤
    27 def main():
    28     if len(sys.argv) > 2:   #要求输入源目录与备份目录
    29         dir1 = sys.argv[1]
    30         dir2 = sys.argv[2]
    31     else:
    32         print "Usage: ", sys.argv[0], "datadir backupdir"
    33         sys.exit()
    34 
    35     source_files = compare_me(dir1, dir2)  #对比源目录与备份目录
    36     dir1 = os.path.abspath(dir1)
    37     if not dir2.endswith('/'):  #备份目录路径加"/"符
    38         dir2 = dir2 + '/'
    39     dir2 = os.path.abspath(dir2)
    40     destination_files = []
    41     createdir_bool = False
    42 
    43     for item in source_files:   #遍历返回的差异文件或目录清单
    44         destination_dir = re.sub(dir1, dir2, item)   #将源目录差异路径清单对应替换成备份目录
    45         destination_files.append(destination_dir)
    46         if os.path.isdir(item):  #如果差异路径为目录且不存在,则备份目录中创建
    47             if not os.path.exists(destination_dir):
    48                 os.makedirs(destination_dir)
    49                 createdir_bool = True  #再次调用compareme函数标记
    50 
    51      ##对应第三个步骤    
    52     if createdir_bool:   #重新调用compareme函数,重新遍历新创建目录的内容
    53         destination_files = []
    54         source_files = []
    55         source_files = compare_me(dir1, dir2)   #调用compareme函数
    56         for item in source_files:   #获取源目录差异路径清单,对应替换成备份目录
    57             destination_dir = re.sub(dir1, dir2, item)
    58             destination_files.append(destination_dir)
    59 
    60     ##对应第四个步骤
    61     print "update item: "
    62     print source_files  #输出更新项列表清单
    63     copy_pair = zip(source_files, destination_files)  #将源目录与备份目录文件清单拆分成元祖
    64     print "copy_pair is %s" % copy_pair
    65     for item in copy_pair:
    66         print "item is %s,  %s" % (item[0], item[1])
    67         if os.path.isfile(item[0]):   #判断是否为文件,是则进行复制操作
    68             shutil.copyfile(item[0], item[1])
    69 
    70 if __name__ == '__main__':
    71     main()
  • 相关阅读:
    一个简单的php站点配置
    nginx基本配置
    redis命令大全
    while()
    遍历字符串
    带空格的字符串逆转(简洁版)
    Java Swing 介绍
    java键盘输入
    做一个完整的Java Web项目需要掌握的技能
    biu
  • 原文地址:https://www.cnblogs.com/watchslowly/p/8227924.html
Copyright © 2020-2023  润新知