如何在 Python 中比较文件

如何在 Python 中比较文件

问题

你需要在 Python 中比较文件。

解决方案

Python 中,可以使用 filecmp 模块来比较文件和目录。1.

cmp(file1, file2[, shallow])

filecmp 会比较文件 file1 和 file2,如果文件相同则返回 True,否则返回 False。默认情况下,根据 os.stat() 返回的相同属性被认为是相等的。如果没有提供 shallow(或者为 True),则认为具有相同的 stat 签名的文件相等。

cmpfiles(dir1, dir2, common[, shallow])

比较列表 common 中包含的文件在两个目录 dir1 和 dir2 中的文件内容。 cmpfiles 会返回一个元组,其中包含三个列表 – 匹配的 match,不匹配的 mismatch,以及由于某些原因无法比较的 errors 的文件名。

  • match – 列出了两个目录中相同的文件。

  • mismatch – 列出了不匹配的文件。

  • errors – 列出了无法比较的文件。

dircmp(dir1, dir2 [, ignore[, hide]])

创建一个目录比较对象,该对象可用于在目录 dir1 和 dir2 上执行各种比较操作。

  • ignore – 忽略要忽略的文件名的列表,默认值为 [‘RCS’,’CVS’,’tags’]。

  • hide – 要隐藏的文件名列表,默认列表为 [os.curdir,os.pardir](在 UNIX 上为 [‘.’,’..’])。

filecmp.dircmp 的实例实现了以下方法,这些方法将在 sys.stdout 上打印详细报告:

  • report():打印两个目录之间的比较。

  • report_partial_closure():打印两个目录的比较以及两个目录的直接子目录的比较。 directories.

  • report_full_closure():打印两个目录、它们所有的子目录、所有这些子目录的子目录等等(即递归)之间的比较。

  • left_list:在路径 path1 中找到的文件和子目录,不包括 hidelist 中的元素。

  • right_list:在路径 path2 中找到的文件和子目录,不包括 hidelist 中的元素。

  • common:在路径 path1 和路径 path2 中都存在的文件和子目录。

  • left_only:仅在路径 path1 中存在的文件和子目录。

  • right_only:仅在路径 path2 中存在的文件和子目录。

  • common_dirs:在路径 path1 和路径 path2 中都存在的子目录。

  • common_files:在路径 path1 和路径 path2 中都存在的文件。

  • same_files:路径 path1 和路径 path2 中内容相同的文件路径。

  • diff_files:在路径 path1 和路径 path2 中都存在但内容不同的文件路径。

  • funny_files:在路径 path1 和路径 path2 中都存在但是由于某些原因无法进行比较的文件路径。

  • subdirs:将 common_dirs 中的名称映射到 dircmp 对象的字典。

为比较准备测试数据。

import os
# 准备测试数据
def makefile(filename,text=None):
"""
函数:制作一些文件
参数:输入文件,正文
"""

with open(filename, 'w') as f:
f.write(text or filename)

return

# 准备测试数据
def makedirectory(directory_name):
"""
函数:制作目录
参数:输入目录
"""
if not os.path.exists(directory_name):
os.mkdir(directory_name)


# 获取当前工作目录
present_directory = os.getcwd()

# 切换到提供的目录
os.chdir(directory_name)

# 制作两个目录
os.mkdir('dir1')
os.mkdir('dir2')

# 制作两个相同的子目录
os.mkdir('dir1/common_dir')
os.mkdir('dir2/common_dir')

# 制作两个不同的子目录
os.mkdir('dir1/dir_only_in_dir1')
os.mkdir('dir2/dir_only_in_dir2')

# 在每个目录中制作一个唯一的文件
makefile('dir1/file_only_in_dir1')
makefile('dir2/file_only_in_dir2')

# 在每个目录中制作一个唯一的文件
makefile('dir1/common_file', '你好,写入相同内容')
makefile('dir2/common_file', '你好,写入相同内容')

# 制作每个目录中的非唯一文件
makefile('dir1/not_the_same')
makefile('dir2/not_the_same')

makefile('dir1/file_in_dir1', '这是dir1中的一个文件')

os.mkdir('dir2/file_in_dir1')

os.chdir(present_directory)

return

if __name__ == '__main__':
os.chdir(os.getcwd())
makedirectory('example')
makedirectory('example/dir1/common_dir')
makedirectory('example/dir2/common_dir')
  • filecmp示例 运行filecmp示例。shallow参数告诉cmp()是否查看文件的内容,以及其元数据。

默认情况下,使用来自os.stat()的信息执行浅层比较。如果结果相同,则认为文件相同。因此,即使它们的内容不同,大小相同且在同一时间创建的文件也被报告为相同的文件。

当shallow为False时,始终比较文件的内容。

import filecmp

print('输出 \n *** 共同文件:', end=' ')

print(filecmp.cmp('example/dir1/common_file',
'example/dir2/common_file'), end=' ')

print(filecmp.cmp('example/dir1/common_file',
'example/dir2/common_file', shallow=False))

print(' *** 不同的文件:', end=' ')

print(filecmp.cmp('example/dir1/not_the_same',
'example/dir2/not_the_same'), end=' ')

print(filecmp.cmp('example/dir1/not_the_same',
'example/dir2/not_the_same', shallow=False))

print(' *** 相同的文件:', end=' ')

print(filecmp.cmp('example/dir1/file_only_in_dir1',
'example/dir1/file_only_in_dir1'), end=' ')

print(filecmp.cmp('example/dir1/file_only_in_dir1',
'example/dir1/file_only_in_dir1', shallow=False))

输出

*** 共同文件: True True
*** 不同的文件: False False
*** 相同的文件: True True
  • cmpfiles示例:

使用cmpfiles()比较两个目录中一组文件而不进行递归。

import filecmp

import os

# 确定同时存在于两个目录中的项目。
dir1_contents = set(os.listdir('example/dir1'))
dir2_contents = set(os.listdir('example/dir2'))
common = list(dir1_contents & dir2_contents)

common_files = [f for f in common if os.path.isfile(os.path.join('example/dir1', f))]

print(f' *** 共同的文件是:{common_files}')

# 现在,让我们比较这些目录
match, mismatch, errors = filecmpfiles(
'example/dir1',
'example/dir2',
common_files,)

print(f' *** 匹配的文件是:{match}')
print(f' *** 不匹配的文件是:{mismatch}')
print(f' *** 错误的文件是:{errors}')
*** 共同的文件是:['file_in_dir1', 'not_the_same', 'common_file']
*** 匹配的文件是:['common_file']
*** 不匹配的文件是:['file_in_dir1', 'not_the_same']
*** 错误的文件是:[]

7. 比较目录。

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print(f"输出 \n *** 打印详细报告:\n ")
print(dc.report())
print(f"\n")
print(dc.report_full_closure())

输出结果

*** 打印详细报告:

差异 example/dir1 和 example/dir2
example/dir1 独有: ['dir_only_in_dir1', 'file_only_in_dir1']
example/dir2 独有: ['dir_only_in_dir2', 'file_only_in_dir2']
相同文件: ['common_file']
不同文件: ['not_the_same']
共同子目录: ['common_dir']
共同特殊情况: ['file_in_dir1']
None

差异 example/dir1 和 example/dir2
example/dir1 独有: ['dir_only_in_dir1', 'file_only_in_dir1']
example/dir2 独有: ['dir_only_in_dir2', 'file_only_in_dir2']
相同文件: ['common_file']
不同文件: ['not_the_same']
共同子目录: ['common_dir']
共同特殊情况: ['file_in_dir1']

差异 example/dir1\common_dir 和 example/dir2\common_dir
共同子目录: ['dir1', 'dir2']

差异 example/dir1\common_dir\dir1 和 example/dir2\common_dir\dir1
相同文件: ['common_file', 'file_in_dir1', 'file_only_in_dir1', 'not_the_same']
共同子目录: ['common_dir', 'dir_only_in_dir1']

差异 example/dir1\common_dir\dir1\common_dir 和 example/dir2\common_dir\dir1\common_dir

差异 example/dir1\common_dir\dir1\dir_only_in_dir1 和 example/dir2\common_dir\dir1\dir_only_in_dir1

差异 example/dir1\common_dir\dir2 和 example/dir2\common_dir\dir2
相同文件: ['common_file', 'file_only_in_dir2', 'not_the_same']
共同子目录: ['common_dir', 'dir_only_in_dir2', 'file_in_dir1']

差异 example/dir1\common_dir\dir2\common_dir 和 example/dir2\common_dir\dir2\common_dir

差异 example/dir1\common_dir\dir2\dir_only_in_dir2 和 example/dir2\common_dir\dir2\dir_only_in_dir2

差异 example/dir1\common_dir\dir2\file_in_dir1 和 example/dir2\common_dir\dir2\file_in_dir1
None

您可以进一步尝试Point1中提到的所有命令,以查看每种方法的行为方式。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程