Python之filecmp模块的使用

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')
filecmp_mkexamples.py

测试效果

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))
filecmp_cmp.py

测试效果

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)
filecmp_cmpfiles.py

测试效果

文件名 ['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()
filecmp_dircmp_report.py

测试效果

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()
filecmp_dircmp_report_full_closure.py

测试效果

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)
filecmp_dircmp_list.py

测试效果

左边的差异
['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、指定忽略比较的文件名,进行文件比较

import filecmp
import pprint

dc = filecmp.dircmp('example/dir1',
                    'example/dir2',
                    ignore=['common_file'])
print('左边的差异')
pprint.pprint(dc.left_list)
print('右边的差异')
pprint.pprint(dc.right_list)
filecmp_dircmp_list_filter.py

测试效果

左边的差异
['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)
filecmp_dircmp_membership.py

测试效果

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)
filecmp_dircmp_common.py

测试效果

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)
filecmp_dircmp_diff.py

测试效果

Same:
['common_file', 'contents_differ']
Different
[]
Funny:
[]

Process finished with exit code 0

 11、用字典类型,它将目录名映射到新的dircmp对象

import filecmp

dc = filecmp.dircmp('example/dir1',
                    'example/dir2')

print('Subdirectories:')
print(dc.subdirs)
filecmp_dircmp_subdirs.py

 测试效果

Subdirectories:
{'common_dir': <filecmp.dircmp object at 0x000001BB94AC39C8>}
posted @ 2020-05-06 12:01  小粉优化大师  阅读(522)  评论(0编辑  收藏  举报