Python之filecmp模块-文件目录比较

本文详细介绍了Python的filecmp模块,包括如何比较文件内容、批量检查文件差异、目录对比以及忽略特定文件进行比较。通过实例展示了dircmp类的使用,如报告目录差异、全层级对比等,帮助理解文件系统比较的各种场景。
摘要由CSDN通过智能技术生成

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')

测试效果

img

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>}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值