ディレクトリ内で最も一般的なファイルまたは頻繁に使用されるファイルを見つけるにはどうすればよいでしょうか?

ディレクトリ内で最も一般的なファイルまたは頻繁に使用されるファイルを見つけるにはどうすればよいでしょうか?

たくさんの画像 (100,000 以上) があるディレクトリがあります。これらの多くは重複または同一の画像ですが、明らかにファイル名はすべて異なります。このディレクトリ内で最も重複が多い画像を見つける必要があります。たとえば、file1.jpeg には 120 個の重複があり、file2.jpeg には 90 個の重複があります。

各ファイルの md5 を取得して何らかの並べ替えを行うことを考えていましたが、詳細はよくわかりません。これはシェル スクリプトで実行できますか?

明確に言うと、重複を削除する必要はなく (まだ)、どのファイルに最も多くのコピーがあるかを見つける必要があります。

参考になれば、私は OS X を使用しています。

答え1

ファイルが完全に重複している場合は、出力を後処理するとshasum * | sort役立つ可能性があります。計算には時間がかかり、複数回必要になる可能性が高いため、ファイルに保存します。

shasum * | sort >/tmp/shasums

たとえば、同一ファイルの分布を確認するには(ファイル名ではなくチェックサムのみで):

</tmp/shasums cut -d ' ' -f 1 | uniq -c

ファイル名と重複数の両方を確認する方法は次のとおりです。

</tmp/shasums sed 's/ .*//' | uniq -c - | join -1 2 - /tmp/shasums | sort -k 2,1

GNU uniq がなければ、次の Perl スクリプトよりもファイル名をわかりやすく表示できる方法はありません。

</tmp/shasums perl -lne '
    s/^([^ ]*?)  //; # set $1 to the checksum and $2 to the filename
    push @{$names{$1}}, $_; # dispatch file names by checksum
    END {
        # iterate through the checksums, sorted by repeat count
        foreach (sort {@$a <=> @$b} values %names) {
            # print the repeat count and the file names
            printf "%d %s\n", scalar(@$_), join(" ", @$_)
        }
    }'

答え2

これは、ハイフンの行の間に重複する名前を出力する、手っ取り早いパイプラインです。現在のディレクトリのみを検索しますが、find再帰検索を行うために使用できます。

md5sum *.jpeg | sort | awk '{if ($1 != prev) print "-----"; print $2; prev = $1}'

出力例:

-----
unique1.jpeg
-----
dup1.jpeg
dup2.jpeg
dup3.jpeg
-----
same1.jpeg
same2.jpeg
-----
solo1.jpeg

関連情報