nファイル数の比較(バイナリ)
-
27-10-2019 - |
質問
いくつかのファイルを比較して、どのファイルが同じファイルを見つけたいのですが、必ずしもテキストファイルではありません(だから提案しないでください diff
)
ファイルは任意の形式(つまり、バイナリファイル)であることができます。
走ることができることがわかりました md5sum
各ファイルのハッシュを見つけてから、手動で比較して、それらが同じかどうかを確認します。しかし、どうすればこのプロセスを自動化できますか?
PS:MD5Sumsを使用してファイルに保存できることもわかりました
md5sum <file-names> | cat >md5sum.txt
しかし、私はこのプロセスを自動化する方法に固執しています。
私はこれをスクリプト(言語なし)で行うことを好みます。
解決
PerlやPythonなどの言語を使用することができれば、ハッシュ/辞書を組み込んだサポートを備えている場合は、本当に簡単です。
ファイル名と署名のループをループし、MD5Sumをキーとしてハッシュを作成し、そのMD5を値としてファイルのリストにします。
次に、ハッシュのコンテンツをループし、複数のアイテムでエントリを表示します。これらは同一である可能性が高いファイルです(署名ベースのアプローチでは本当に確実ではありません)。
人々がコードを求めているように、おそらく以下のようなものです。それはPerlの実装です。必要に応じて、後で同等のPythonサンプルを追加する場合があります。
#!perl
my $same = {};
for my $x (@ARGV){
my ($sig, $name) = split(/\s+/, `md5sum $x`);
if (!defined($same{$sig})){$same{$sig} = []}
push @{$same{$sig}}, $name;
}
for my $sig (keys %same){
if (@{$same{$sig}} > 1){
print "Files with same MD5 : ".join('-', @{$same{$sig}})."\n";
}
}
それを同じファイルに入れて、同じようにしてください、あなたはそれを次のように呼びます
perl same.pl
使用の例:
$ md5sum F*
c9904273735f3141c1dd61533e02246a F1
c9904273735f3141c1dd61533e02246a F2
c9904273735f3141c1dd61533e02246a F3
d41d8cd98f00b204e9800998ecf8427e F4
$ perl same.pl F1 F2 F3 F4
Files with same MD5 : F1-F2-F3
以下は、可能なPythonバージョンです(Python2とPython3の両方で動作します)。
#!python
import hashlib
def md5sum(filename):
f = open(filename, mode='rb')
buf = f.read(128)
d = hashlib.md5(buf)
while len(buf) == 128:
buf = f.read(128)
d.update(buf)
return d.hexdigest()
if __name__ == "__main__":
import sys
same = {}
for name in sys.argv[1:]:
sig = md5sum(name)
same.setdefault(sig, []).append(name)
for k in same:
if len(same[k]) > 1:
print("Files with same MD5: {l}".format(l="-".join(same[k])))
非常に多数のファイルを比較している場合、上記の例のようにコマンドラインにファイル名を提供する場合は、それを行うためにもっと手の込んだ方法を使用する(またはスクリプト内にグローブを置く)、またはシェルコマンドラインはオーバーフローします。