filecmp模塊用來比較目錄、文件是否相同。舉例如下:
構建兩個文件夾,其結構如圖所示:
其中data內容保持一致,data1內容不一致,data2是tmp獨有,readme1和readme內容一致。
如果單純比較兩個文件是否相同,可以通過filecmp.cmp(f1, f2, shallow=True)實現。其中f1、f2是文件名,shallow=True,則通過文件的元信息比較是否一致,如果是False,則比較兩個文件內容。
import filecmp
from pathlib import Path
def main():
filecmp.clear_cache() # 清除 filecmp 緩存
p = Path(".")
p1 = p / 'tmp' / 'data'
p2 = p / 'tmp' / 'data1'
print(filecmp.cmp(p1, p2))
if __name__ == '__main__':
main()
如果非遞歸比較兩個目錄中的一組文件,可以選擇通過filecmp.cmpfiles(dir1, dir2, common, shallow=True)實現。其中dir1、dir2是兩個文件夾,common是list,裏面是需要比較的共同文件名稱。
import filecmp
from pathlib import Path
def main():
filecmp.clear_cache() # 清除 filecmp 緩存
p = Path(".")
p3 = p / 'tmp'
p4 = p / 'tmp1'
match, mismatch, error = filecmp.cmpfiles(p3, p4, common=['data', 'data1', 'data2'])
print(match, mismatch, error)
if __name__ == '__main__':
main()
對於大目錄樹的遞歸比較或者更完整的分析,可以選擇使用dircmp類。
report() 打印兩個目錄報告,非遞歸
report_full_closure() 遞歸打印兩個目錄
當然也可以通過更低級的API去實現,參見dir_files_diff()
import filecmp
from filecmp import dircmp
from pathlib import Path
def dir_files_diff(dcmp: dircmp):
for name in dcmp.common_files:
print("the same file found in two dirs: %s" % name)
for name in dcmp.diff_files:
print("diff file found in two dirs: %s" % name)
for name_left in dcmp.left_only:
print("only found in left dir: %s/%s" % (dcmp.left, name_left))
for name_right in dcmp.right_only:
print("only found in right dir: %s/%s" % (dcmp.right, name_right))
for sub_dcmp in dcmp.subdirs.values():
dir_files_diff(sub_dcmp)
def main():
filecmp.clear_cache() # 清除 filecmp 緩存
p = Path(".")
dcmp = dircmp(p3, p4)
dcmp.report() # 只包括給定目錄的內容的報告
dcmp.report_full_closure() # 遞歸比較後的報告
dir_files_diff(dcmp) # 自定義比較
if __name__ == '__main__':
main()
整體效果: