Python之filecmp模块的使用
目录对比
目录对比,通过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对象,格式为字典的类型。
filecmp模块作用
主要用于比较文件系统上的文件和目录
1、创建演示的目录
import os
def mkfile(filename, body=None):
# 创建文件,内容没有设置则写入文件名,有传内容则传写指定的内容
with open(filename, 'w') as f:
f.write(body or filename)
return None
def make_example_dir(top):
if not os.path.exists(top):
os.mkdir(top)
# 获取当前的目录
curdir = os.getcwd()
# 修改当前的目录位置
os.chdir(top)
# 创建两个目录
os.mkdir('dir1')
os.mkdir('dir2')
# 创建两个文件
mkfile('dir1/file_only_in_dir1')
mkfile('dir2/file_only_in_dir2')
# 创建两个目录
os.mkdir('dir1/common_dir')
os.mkdir('dir2/common_dir')
# 创建一个文件并且写入指定的内容,并且创建一个软链接到dir2
mkfile('dir1/common_file', 'this file is the same')
os.link('dir1/common_file', 'dir2/common_file')
# 创建两个文件
mkfile('dir1/contents_differ')
mkfile('dir2/contents_differ')
# 更新访问时间和修改时间
st = os.stat('dir1/contents_differ')
os.utime('dir2/contents_differ', (st.st_atime, st.st_mtime))
# 创建文件和目录
mkfile('dir1/file_in_dir1', 'This is a file in dir1')
os.mkdir('dir2/file_in_dir1')
# 恢复当前的目录
os.chdir(curdir)
return None
if __name__ == '__main__':
os.chdir(os.path.dirname(__file__) or os.getcwd())
make_example_dir('example')
make_example_dir('example/dir1/common_dir')
make_example_dir('example/dir2/common_dir')
测试效果
2、比较文件内容
import filecmp
# 比较common_file文件
# shallow=True : 只比较文件数据元信息。
print('common_file :', end=' ')
print(filecmp.cmp('example/dir1/common_file',
'example/dir2/common_file',
shallow=True), end=' ')
# shallow=False : 除了比较文件数据元信息,还要读取文件内容比较。
print(filecmp.cmp('example/dir1/common_file',
'example/dir2/common_file',
shallow=False))
# 比较contents_differ文件
print('contents_differ:', end=' ')
print(filecmp.cmp('example/dir1/contents_differ',
'example/dir2/contents_differ',
shallow=True), end=' ')
print(filecmp.cmp('example/dir1/contents_differ',
'example/dir2/contents_differ',
shallow=False))
# 比较file_only_in_dir*文件
print('contents_differ:', end=' ')
print(filecmp.cmp('example/dir1/file_only_in_dir1',
'example/dir2/file_only_in_dir2',
shallow=True), end=' ')
print(filecmp.cmp('example/dir1/file_only_in_dir1',
'example/dir2/file_only_in_dir2',
shallow=False))
测试效果
common_file : True True
contents_differ: True False
contents_differ: False False
3、批量比较文件的差异
import filecmp
import os
d1_contents = set(os.listdir('example/dir1'))
d2_contents = set(os.listdir('example/dir2'))
# 求交集,去重
common = list(d1_contents & d2_contents)
# 判断是否是文件
common_files = [
f
for f in common
if os.path.isfile(os.path.join('example/dir1', f))
]
print('文件名', common_files)
match, mismatch, errors = filecmp.cmpfiles(
'example/dir1',
'example/dir2',
common_files
)
print('匹配到 :', match)
print('匹配不到 :', mismatch)
print('错误 :', errors)
测试效果
文件名 ['common_file', 'contents_differ', 'file_in_dir1']
匹配到 : ['common_file', 'contents_differ']
匹配不到 : ['file_in_dir1']
错误 : []
*4、目录的比较差异*
import filecmp
dc = filecmp.dircmp('example/dir1',
'example/dir2')
dc.report()
测试效果
diff example/dir1 example/dir2
Only in example/dir1 : ['file_only_in_dir1']
Only in example/dir2 : ['file_only_in_dir2']
Identical files : ['common_file', 'contents_differ']
Common subdirectories : ['common_dir']
Common funny cases : ['file_in_dir1']
5、所有同级目录的比较
import filecmp
dc = filecmp.dircmp('example/dir1',
'example/dir2')
dc.report_full_closure()
测试效果
diff example/dir1 example/dir2
Only in example/dir1 : ['file_only_in_dir1']
Only in example/dir2 : ['file_only_in_dir2']
Identical files : ['common_file', 'contents_differ']
Common subdirectories : ['common_dir']
Common funny cases : ['file_in_dir1']
diff example/dir1\common_dir example/dir2\common_dir
Common subdirectories : ['dir1', 'dir2']
diff example/dir1\common_dir\dir1 example/dir2\common_dir\dir1
Identical files : ['common_file', 'contents_differ', 'file_in_dir1', 'file_only_in_dir1']
Common subdirectories : ['common_dir']
diff example/dir1\common_dir\dir1\common_dir example/dir2\common_dir\dir1\common_dir
diff example/dir1\common_dir\dir2 example/dir2\common_dir\dir2
Identical files : ['common_file', 'contents_differ', 'file_only_in_dir2']
Common subdirectories : ['common_dir', 'file_in_dir1']
diff example/dir1\common_dir\dir2\common_dir example/dir2\common_dir\dir2\common_dir
diff example/dir1\common_dir\dir2\file_in_dir1 example/dir2\common_dir\dir2\file_in_dir1
6、指定参照目录,匹配左边或右边的差异
import filecmp
import pprint
dc = filecmp.dircmp('example/dir1',
'example/dir2')
print('左边的差异')
pprint.pprint(dc.left_list)
print('右边的差异')
pprint.pprint(dc.right_list)
测试效果
左边的差异
['common_dir',
'common_file',
'contents_differ',
'file_in_dir1',
'file_only_in_dir1']
右边的差异
['common_dir',
'common_file',
'contents_differ',
'file_in_dir1',
'file_only_in_dir2']
7、指定忽略比较的文件名,进行文件比较
测试效果
左边的差异
['common_dir', 'contents_differ', 'file_in_dir1', 'file_only_in_dir1']
右边的差异
['common_dir', 'contents_differ', 'file_in_dir1', 'file_only_in_dir2']
8、比较每个目录唯一的差异和公共的目录显示
import filecmp
import pprint
dc = filecmp.dircmp('example/dir1',
'example/dir2')
print('Common:')
pprint.pprint(dc.common)
print('左边的差异')
pprint.pprint(dc.left_only)
print('右边的差异')
pprint.pprint(dc.right_list)
测试效果
Common:
['common_dir', 'common_file', 'contents_differ', 'file_in_dir1']
左边的差异
['file_only_in_dir1']
右边的差异
['common_dir',
'common_file',
'contents_differ',
'file_in_dir1',
'file_only_in_dir2']
Process finished with exit code 0
9、目录比较,分解显示文件名
import filecmp
import pprint
dc = filecmp.dircmp('example/dir1',
'example/dir2')
print('Common:')
pprint.pprint(dc.common)
print('Directories')
pprint.pprint(dc.common_dirs)
print('Files:')
pprint.pprint(dc.common_files)
print('Funny:')
pprint.pprint(dc.common_funny)
测试效果
Common:
['common_dir', 'common_file', 'contents_differ', 'file_in_dir1']
Directories
['common_dir']
Files:
['common_file', 'contents_differ']
Funny:
['file_in_dir1']
10、比较os.stat()文件信息,不比较文本内容
import filecmp
import pprint
dc = filecmp.dircmp('example/dir1',
'example/dir2')
print('Same:')
pprint.pprint(dc.same_files)
print('Different')
pprint.pprint(dc.diff_files)
print('Funny:')
pprint.pprint(dc.funny_files)
测试效果
Same:
['common_file', 'contents_differ']
Different
[]
Funny:
[]
Process finished with exit code 0
11、用字典类型,它将目录名映射到新的dircmp对象
filecmp_dircmp_subdirs.py
测试效果
Subdirectories:
{'common_dir': <filecmp.dircmp object at 0x000001BB94AC39C8>}