大容量の音楽コレクションをハードドライブに保存しています。調べてみると、いくつかのアルバムディレクトリに重複したファイルがたくさんあることがわかりました。通常、重複は元のディレクトリと同じディレクトリに存在します。
通常、形式はfilename.mpで、重複ファイルはfilename 1.mpです。場合によっては、複数の重複ファイルが存在する可能性があり、フォルダ間で重複ファイルがあるかどうか(たとえば、アルバムディレクトリの重複)がわかりません。
これらの重複ファイルをスキャンして(たとえば、ファイルサイズを比較したり、ファイル全体を比較して同一かどうかを確認したり)、結果を確認してから重複を削除する方法はありますか?長い名前を持つもの、またはより最近変更/作成された日付を持つものは、通常、削除の対象になります。
Linuxでこれを実行できるプログラムはありますか?
そのようなプログラムがあり、それはrdfind
と呼ばれます:
SYNOPSIS
rdfind [ options ] directory1 | file1 [ directory2 | file2 ] ...
DESCRIPTION
rdfind finds duplicate files across and/or within several directories.
It calculates checksum only if necessary. rdfind runs in O(Nlog(N))
time with N being the number of files.
If two (or more) equal files are found, the program decides which of
them is the original and the rest are considered duplicates. This is
done by ranking the files to each other and deciding which has the
highest rank. See section RANKING for details.
重複を削除したり、シンボリックリンクやハードリンクに置き換えたりできます。
ふん。私は、この重複であることが判明した質問のために、すべての重複をリストするワンライナーを開発しました。なんてメタ。まあ、それを無駄にするのは残念なので、私はそれを投稿しますが、rdfind
はより良い解決策のように思えます。
これには少なくとも、「実際の」Unixの方法であるという利点があります;)
find -name '*.mp3' -print0 | xargs -0 md5sum | sort | uniq -Dw 32
パイプラインを分解する:
find -name '*.mp3' -print0
現在のディレクトリから始まるサブツリー内のすべてのmp3ファイルを検索し、NUL区切りの名前を出力します。
xargs -0 md5sum
NULで区切られたリストを読み取り、各ファイルのチェックサムを計算します。
あなたはsort
が何をするか知っています。
uniq -Dw 32
は、ソートされた行の最初の32文字を比較し、同じハッシュを持つものだけを出力します。
したがって、すべての重複のリストが作成されます。その後、削除したいものまで手動で削って、ハッシュを削除し、リストをrm
にパイプします。
私はPerlの使用を考えています:
#!/usr/bin/Perl
use strict;
use warnings;
use File::Find;
use Digest::SHA qw ( sha1_hex );
my %seen;
sub find_dupes {
next if -d;
local $/;
open( my $input, "<", $File::Find::name ) or warn $!;
my $sha1sum = sha1_hex(<$input>);
close($input);
if ( $seen{$sha1sum} ) {
print "$File::Find::name is probably a dupe of $seen{$sha1sum} - both have $sha1sum\n";
}
$seen{$sha1sum} = $File::Find::name;
}
find( \&find_dupes, "/path/to/search", "/another/path/to/search" );