
私が達成したいのは、ディレクトリ内のすべてのファイルをインポートし、内容の一意性に従ってリスト/ソートすることです。
例:
私たちのディレクトリに7つのファイルがあるとします。
uniquefile1.txt, uniquefile2.txt, samefile1.txt, samefile2.txt, equalfile1.txt, equalfile2.txt, equalfile3.txt
ここで、Uniquefile1 と Uniquefile2 の内容は互いに異なり、すべての Samefile.txt は互いに同じ内容を持ち、すべての Equalfile.txt は互いに同じ内容を持ちます。
予想出力:
uniquefile1.txt
uniquefile2.txt
samefile1.txt, samefile2.txt
equalfile1.txt, equalfile2.txt, equalfile3.txt
私はハッシングとmd5sumを使ってきましたが、これを行うために何も得られませんでした。
必要に応じて、grep、xargs、sed、awk、find、locatedなどのユーティリティを他のcoreutilと混合してこれを実行したいと思います。
答え1
修正された部分です昨日書いた答え:
$ cksum file* | awk '{ ck[$1$2] = ck[$1$2] ? ck[$1$2] ", " $3 : $3 } END { for (i in ck) print ck[i] }'
file3, file5
file1, file2, file4
*.txt
あなたの場合は、代わりにまたはeven *
(比較したいディレクトリにファイルのみがある場合)を使用してくださいfile*
。
結果は、file3
andがandfile5
と同じ内容を持っていることを示しています(この場合)。file1
file2
file4
標準cksum
ユーティリティは、各ファイルに対して3つの列を出力します。 1つ目はチェックサム、2つ目はファイルサイズ、3つ目はファイル名です。
コードawk
はチェックサムとサイズを配列のキーとして使用ck
し、そのキーのコンマ区切り文字列に同じキーを持つファイル名を格納します。最後に、ファイル名(カンマ区切り文字列)を印刷します。
面白い
ck[$1$2] = ck[$1$2] ? ck[$1$2] ", " $3 : $3
ck[$1$2]
「何でも設定すると割り当てck[$1$2] ", " $3
(ck[$1$2]
ファイル名の間にカンマを追加)、それ以外の場合は割り当て$3
(このキーを持つ最初のファイル名)」を意味します。
各リストの項目数に基づいて出力をソートするには、出力を次に渡します。
awk -F, '{ print NF, $0 }' | sort -n | cut -d ' ' -f 2-
...後処理段階です。ファイル名にカンマが含まれていると、明らかに壊れてしまいます。
または使用
cksum file* | awk '{ n[$1$2]++; ck[$1$2] = ck[$1$2] ? ck[$1$2] ", " $3 : $3 } END { for (i in ck) print n[i], ck[i] }' | sort -n | cut -d ' ' -f 2-
ファイル名にカンマがある場合は問題ありません。
cut
各出力行のファイル名の数を表示するには、このオプションを無視してください。
多数のファイルに使用できます。
find . -type f -exec cksum {} +
そして同様に
cksum *
答え2
私は以下を使用しますperl
:
perl -MDigest::SHA -le '
for $f (@ARGV) {
$d = Digest::SHA->new(256);
$d->addfile($f);
push @{$h{$d->digest}}, $f
}
print join ", ", @{$h{$_}} for keys %h' -- *.txt
私たちは、キーがファイルのsha256ハッシュであり、その値が対応するハッシュを持つファイルのリストである連想配列を構築しています。
発生回数に応じて出力を簡単に整列できます。たとえば、次のようになります。
perl -MDigest::SHA -le '
for $f (@ARGV) {
$d = Digest::SHA->new(256);
$d->addfile($f);
push @{$h{$d->digest}}, $f
}
print join ", ", @{$h{$_}} for sort {@{$h{$a}} <=> @{$h{$b}}} keys %h' -- *.txt
または、各グループのファイルリストをファイル名で並べ替えることもできます。
perl -MDigest::SHA -le '
for $f (@ARGV) {
$d = Digest::SHA->new(256);
$d->addfile($f);
push @{$h{$d->digest}}, $f
}
print join ", ", sort {$a cmp $b} @{$h{$_}} for
sort {@{$h{$a}} <=> @{$h{$b}}} keys %h' -- *.txt