web-dev-qa-db-ja.com

スペースと改行を無視して同一のファイルをクラスタリングする

多くのXMLファイル(10Kの小さなテキストファイル)を含むフォルダーについて考えてみます。一部のXMLファイルは同一であり、一部は異なります。

どのファイルが同一であるか(空白、タブ、改行を無視)を調べて、各クラスターのファイルを何らかの方法で記録したいと思います。

これには高精度は必要ないので、これを行う1つの方法は、MD5または他のハッシュアルゴリズムを使用することです。つまり、同じ正確なMD5合計を持つファイルの数を数えますが、スペースを事前に削除する必要があります。 。

私はOSXを使用しており、次のようにファイルのMD5を確認できます。

$ md5 file_XYZ.xml
MD5 (file_XYZ.xml) = 0de0c7bea1a75434934c3821dcba759a

これを使用して同一のファイルをクラスター化するにはどうすればよいですか? (同じハッシュのファイル名を持つテキストファイル、またはフォルダー内のファイルのクラスタリングのいずれかがそれを行います)

次のようなものを使用して、各XMLファイルの「正規化された」バージョンを作成できます。

xmllint --nospace --format orginal.xml > normalized.xml

これにより、XMLにとって「重要でない」空白が削除され、一貫してインデントされます。その後、cksumを使用して、同一の正規化ファイルを見つけることができます。

スクリプトを提案します:

for ORIGXML in *.xml
do
    xmllint --noblank --format "$ORIGXML" > "normalized.$ORIGXML"
    cksum "normalized.$ORIGXML" | sed 's/^normalized\.//' >> files.list
done
sort -k1.1 files.list > sorted.files

MD5チェックサムを気にするかどうかはわかりません。あなたは、あなたに反対する邪悪な敵と暗号化を行うのではなく、重複を探しています。

「ほぼ同一の」XMLファイルを探している場合は、 正規化された圧縮距離 を使用して、ファイルが互いにどの程度「離れている」かを確認できます。もっと簡単に言えば、gzipまたはbzip2 XMLファイル、次に圧縮ファイルサイズに基づいてソートします。圧縮ファイルサイズが近いほど、XMLファイルは同一になります。

2
Bruce Ediger