filecmp を使ってファイルやディレクトリの比較をしてみたので、その時のメモをここに残します。
filecmp とは
filecmp モジュールは、ファイルとディレクトリを比較するものです。
使い方
ファイルの比較
f1 と f2 という名前のファイルを比較し、等しいと思われる場合は True を返し、そうでない場合は False を返します。
filecmp.cmp(f1, f2, shallow=True)
shallow がデフォルトまたは True 指定の場合はファイルを読み込んでバイトでの比較となるため、ファイル内容で比較したい場合は、引数を shallow を False にします。
ディレクトリにあるファイルの比較
common で名前が付けられている dir1 と dir2 の2つのディレクトリにあるファイルを比較します。
filecmp.cmpfiles(dir1, dir2, common, shallow=True)
一致、不一致、エラーの3つのファイル名のリストを返します。 match には一致するファイルのリストが含まれ、 missmatch には一致しないファイルの名前が含まれ、 errors には比較できなかったファイルの名前が含まれます。
ファイルがディレクトリの1つに存在しない場合、ユーザーにファイルを読み取る権限がない場合、またはその他の理由で比較を実行できなかった場合、ファイルはエラーにリストされます。
ディレクトリ比較
dir1 と dir2 を比較します。
cmp = filecmp.dircmp(dir1, dir2, ignore=None, hide=None) # 比較 cmp.report()
サンプル
ファイルの比較
評価用ファイル
$ cat bar.log bar $ cat foo.log foo
コード
import filecmp f1="foo.log" f2="bar.log" print("ファイルの比較") print(f" - 差分無: {filecmp.cmp(f1, f1, shallow=True)}") print(f" - 差分有: {filecmp.cmp(f1, f2, shallow=True)}")
実行結果
$ python sample.py ファイルの比較 - 差分無: True - 差分有: False
ディレクトリにあるファイルの比較
評価用ファイル
$ tree foo* bar* foo1 ├── foo.log └── hoge.txt foo2 ├── foo.log └── hoge.txt bar1 └── bar.log bar2 └── bar.log
コード
import filecmp f1 = "foo.log" f2 = "bar.log" d1_1 = "foo1" d1_2 = "foo2" d2_1 = "bar1" d2_2 = "bar2" cmd_1 = filecmp.cmpfiles(d1_1, d1_1, [f1], shallow=True) print(f"同じディレクトリを比較: {cmd_1}") cmd_2 = filecmp.cmpfiles(d1_1, d1_2, [f1], shallow=True) print(f"ファイルに差分有り比較: {cmd_2}") cmd_3 = filecmp.cmpfiles(d1_1, d2_1, [f1], shallow=True) print(f"片側に存在しない指定ファイル無: {cmd_3}")
実行結果
$ python sample.py 同じディレクトリを比較: (['foo.log'], [], []) ファイルに差分有り比較: ([], ['foo.log'], []) 片側に存在しない指定ファイル無: ([], [], ['foo.log'])
ディレクトリ比較
評価用ファイル
$ tree foo* bar* foo1 ├── foo.log └── hoge.txt foo2 ├── foo.log └── hoge.txt bar1 └── bar.log bar2 └── bar.log
コード
import filecmp f1 = "foo.log" f2 = "bar.log" d1_1 = "foo1" d1_2 = "foo2" d2_1 = "bar1" d2_2 = "bar2" cmp_1 = filecmp.dircmp(d1_1, d1_1) print(f"同じディレクトリ: {cmp_1.report()}\n") cmp_2 = filecmp.dircmp(d1_1, d1_2) print(f"差分有りのファイル含む: {cmp_2.report()}\n") cmp_3 = filecmp.dircmp(d1_1, d2_1) print(f"違うディレクトリでファイルも異なる: {cmp_3.report()}\n")
実行結果
$ python sample.py diff foo1 foo1 Identical files : ['foo.log', 'hoge.txt'] 同じディレクトリ: None diff foo1 foo2 Identical files : ['hoge.txt'] Differing files : ['foo.log'] 差分有りのファイル含む: None diff foo1 bar1 Only in foo1 : ['foo.log', 'hoge.txt'] Only in bar1 : ['bar.log'] 違うディレクトリでファイルも異なる: None