您的位置:首页 > 编程语言 > Python开发

Python自动化运维笔记(五):使用filecmp模块实现文件以及文件目录差异对比

2017-10-02 17:11 1216 查看
运行环境:
Python3.6
Windwos10 RS1
Pycharm


参考书籍—
《Python自动化运维--技术与最佳实践》
刘天斯著

模块介绍

Python2.3
以上的版本默认自带了
filecmp
模块,无需额外安装。我们可以用这个模块来检查原式与目标文件的一致性,
filecmp
可以实现文件、目录、遍历子目录的差异对比功能。

模块使用

filecmp
提供了三个操作方法。

cmp
:单文件对比

cmpfiles
:多文件对比

dircmp
:目录对比

单文件对比

使用的是
filecmp.cmp(f1,f2[,shallow])
。其中
f1
f2
为文件,当两个文件相同时返回
True
,不同返回
False
,(
shallow
默认为
True
,其意思是只根据
os.stat()
方法返回的文件基本信息进行对比[最后访问时间、修改时间、状态改变时间等,而不考虑文件内容])。当
shallow
False
时,则
os.stat()
与文件内容同时进行校验。

现在我在我代码的当前路径下
4000
有三个分别名为
File1.txt
File2.txt
File3.txt
的文件,
File1.txt
File3.txt
两个文件是单独创建的文本文件,而
File2.txt
File1.txt
的副本文件,即直接由复制文件
File1.txt
并改名
File2.txt
得到。
所以按理来说
File1.txt
File2.txt
两个文件完全相同、而与
File3.txt
文件不同。

下面使用代码进行验证:

Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
>>> import filecmp
>>> filecmp.cmp('./File1.txt', './File2.txt')
True        # 说明两个文件相同,返回True
>>> filecmp.cmp('./File1.txt', './File3.txt')
False       # 说明两个文件不同,返回False


多文件对比

比较两个文件夹内指定文件是否相等。参数
dir1
,
dir2
指定要比较的文件夹,参数
common
指定要比较的文件名列表。函数返回包含3个
list
元素的元组,分别表示匹配、不匹配以及错误的文件列表。错误的文件指的是不存在的文件,或文件被琐定不可读,或没权限读文件,或者由于其他原因访问不了该文件。

# 下列文件是dir1文件夹下所有文件的MD5值
FBAAF8CC3C1DF70B183CB8E8FBDFC57C *File1.txt
FBAAF8CC3C1DF70B183CB8E8FBDFC57C *File2.txt
16EC37C499F64FC60E95650B500E30A4 *File3.txt
202CB962AC59075B964B07152D234B70 *File4.txt

# 下列文件是dir1文件夹下所有文件的MD5值
FBAAF8CC3C1DF70B183CB8E8FBDFC57C *File1.txt
FBAAF8CC3C1DF70B183CB8E8FBDFC57C *File2.txt
D41D8CD98F00B204E9800998ECF8427E *File3.txt
CB30FC9CEC9A2D04EF49B22E2066C264 *File5.txt

# 根据MD5值可以知道,两个文件夹下的File1.txt、File2.txt相匹配,
# 而File3.txt不匹配,
# 另外对于File4.txt和File5.txt两个文件只在各自的目录下存在。


使用示例代码验证:

>>> filecmp.cmpfiles('./dir1', './dir2', ['File1.txt', 'File2.txt', 'File3.txt', 'File4.txt', 'File5.txt'])
(['File1.txt', 'File2.txt'], ['File3.txt'], ['File4.txt', 'File5.txt'])       # 返回为列表
# 列表[0] == 匹配
# 列表[1] == 不匹配
# 列表[2] == 不存在,无法比较


目录对比

目录对比,通过
filecmp(a,b[,ignore[,hide]])
类创建一个目录比较对象用于比较文件夹,通过该类比较两个文件夹,可以获取一些详细的比较结果(如只在A文件夹存在的文件列表),并支持子文件夹的递归比较。

dircmp
提供了三个方法用于报告比较的结果:

report()
:只比较指定文件夹中的内容(文件与文件夹)

report_partial_closure()
:比较文件夹及第一级子文件夹的内容

report_full_closure()
:递归比较所有的文件夹的内容

另外为了输出更加详细的信息,
dircmp
类还提供了以下属性:

left_list
:左边文件夹中的文件与文件夹列表;

right_list
:右边文件夹中的文件与文件夹列表;

common
:两边文件夹中都存在的文件或文件夹;

left_only
:只在左边文件夹中存在的文件或文件夹;

right_only
:只在右边文件夹中存在的文件或文件夹;

common_dirs
:两边文件夹都存在的子文件夹;

common_files
:两边文件夹都存在的子文件;

common_funny
:两边文件夹都存在的子文件夹;

same_files
:匹配的文件;

diff_files
:不匹配的文件;

funny_files
:两边文件夹中都存在,但无法比较的文件;

subdirs
:将
common_dirs
目录映射到新的
dircmp
对象,格式为字典的类型。

示例代码,比较
dir1
dir2
文件夹目录的差异

# -*- coding: utf-8 -*-

import filecmp

a = "./dir1"  # 定义左目录
b = "./dir2"  # 定义右目录

dirobj = filecmp.dircmp(a, b, ['EXT.txt'])  # 目录比较,忽略EXT.txt文件

# 输出对比结果数据报表,详细说明请参考filecmp类方法及属性信息
dirobj.report()
dirobj.report_partial_closure()
dirobj.report_full_closure()
print("left_list:" + str(dirobj.left_list))
print("right_list:" + str(dirobj.right_list))
print("common:" + str(dirobj.common))
print("left_only:" + str(dirobj.left_only))
print("right_only:" + str(dirobj.right_only))
print("common_dirs:" + str(dirobj.common_dirs))
print("common_files:" + str(dirobj.common_files))
print("common_funny:" + str(dirobj.common_funny))
print("same_file:" + str(dirobj.same_files))
print("diff_files:" + str(dirobj.diff_files))
print("funny_files:" + str(dirobj.funny_files))


运行结果下:

C:\Users\imwoo\AppData\Local\Programs\Python\Python36-32\python.exe E:/Python_Test/Code/Auto_Operations/filecmpTest.py
diff ./dir1 ./dir2
Only in ./dir1 : ['File4.txt']
Only in ./dir2 : ['File5.txt']
Identical files : ['File1.txt', 'File2.txt']
Differing files : ['File3.txt']
diff ./dir1 ./dir2
Only in ./dir1 : ['File4.txt']
Only in ./dir2 : ['File5.txt']
Identical files : ['File1.txt', 'File2.txt']
Differing files : ['File3.txt']
diff ./dir1 ./dir2
Only in ./dir1 : ['File4.txt']
Only in ./dir2 : ['File5.txt']
Identical files : ['File1.txt', 'File2.txt']
Differing files : ['File3.txt']
left_list:['File1.txt', 'File2.txt', 'File3.txt', 'File4.txt']
right_list:['File1.txt', 'File2.txt', 'File3.txt', 'File5.txt']
common:['File1.txt', 'File2.txt', 'File3.txt']
left_only:['File4.txt']
right_only:['File5.txt']
common_dirs:[]
common_files:['File1.txt', 'File2.txt', 'File3.txt']
common_funny:[]
same_file:['File1.txt', 'File2.txt']
diff_files:['File3.txt']
funny_files:[]


其实个人觉得上面的信息不太方便理解,所以附上我的一张目录tree图:

├─dir1
│      EXT.txt
│      File1.txt
│      File2.txt
│      File3.txt
│      File4.txt
│
├─dir2
│      EXT.txt
│      File1.txt
│      File2.txt
│      File3.txt
│      File5.txt
│
└─__pycache__
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: