ものづくりのブログ

うちのネコを題材にしたものづくりができたらいいなと思っていろいろ奮闘してます。

【Python】filecmp でファイルやディレクトリの比較

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