私は数十万のファイルを多くの外部ディスクとコンピューターのディスクに分散させており、その多くは複製されています。この混乱は、私が安全提案のためにコピーを作成したことが原因でした。時々、組織のディレクトリ構造を変更しましたが、コピーがあった他の場所には複製されませんでした。
今、私は1つの巨大なディスクを持っており、バックアップが本当に必要で、クラウドにミラーリングされています。
すでにビッグディスクにあるすべての分散ディスクからすべてを削除する方法が欲しいのですが。
シナリオを見せてみましょう:
OldDisk1:
/code/{manystructures}/{manyfiles}
/docs/{manystructures}/{manyfiles}
OldDisk2:
/dev/{another_structures}/{same_files_different_names}
/documents/{another_structures}/{same_files_different_names}
NewHugeDisk:
/home/username/code/{new_strutucture}/{new_files}
/home/username/documents/{new_strutucture}/{new_files}
「すでにNewHugeDiskにあるOldDisk1上のすべてのファイルを見つけて削除する」などのツールや方法を知っている人はいますか?
私は多くのツール(Windows、Mac、Linuxの両方でこの問題が発生しているため)を無料と有料で調べましたが、運がありませんでした。
そして、ideiaはそれを行うためのコードを作成するでしょうが、私は開発者ではありません。小さくて単純なコードはできますが、この種のコードは私にとっては複雑になると思います。
これに関する助けやアイデアをいただければ幸いです。
プロセス全体のOSとしてWindowsを使用でき、 Free Duplicate File Finder (試したことはありませんが、言及されていることがわかりました ここ )が気に入らないと仮定すると、 PowerShellを使用すると、比較的少ない労力で目的を達成できます。注:私はPowerShellの本当のプロではないので、コードを改良できると確信しています。
Powershell ISEを開いて(または、メモ帳がない場合はメモ帳を使用して)、次のコードをコピーして貼り付け、結果のファイルを* .ps1として保存します。また、$oldpath
と$newpath
の値をディレクトリに変更する必要があります。パスを引用符で囲んでください。
# Search-and-Destroy-script
# Get all files of both code-directories:
$oldpath = "Disk1:\code"
$newpath = "DiskNew:\code"
$files_old = Get-ChildItem -Path $oldpath -Recurse -File
$files_new = Get-ChildItem -Path $newpath -Recurse -File
for($i=0; $i -lt $files_old.length; $i++){
$j=0
while($true){
# if last edit time is the same and file-size is the same...
if($($files_old[$i]).length -eq $($files_new[$j]).length -and $($files_old[$i]).lastWriteTime -eq $($files_new[$j]).lastWriteTime){
# Get File-Hashes for those files (SHA1 should be enough)
$files_old_hash = Get-FileHash -Path $($files_old[$i]).FullName -Algorithm SHA1 | ForEach-Object {$_.Hash}
$files_new_hash = Get-FileHash -Path $($files_new[$j]).FullName -Algorithm SHA1 | ForEach-Object {$_.Hash}
# if hashes also are the same...
if($files_old_hash -eq $files_new_hash){
# remove the old file (-Confirm can be removed so you don't have to approve for every file)
# if you want to check the files before deletion, you could also just rename them (here we're adding the suffix ".DUPLICATE"
# Rename-Item -Path $($files_old[$i]).FullName -NewName "$($files_old[$i]).Name.DUPLICATE"
Remove-Item -Path $($files_old[$i]).FullName -Confirm
Write-Host "DELETING`t$($files_old[$i]).FullName" -ForegroundColor Red
break
}
# if files aren't the same...
}else{
# if old_file is compared to all new_files, check next old file
if($j -ge $files_new.length){
break
}
}
$j++
}
}
次に、スクリプトを開始します(たとえば、右クリックして)-それが失敗した場合は、ExecutionPolicy
が設定されていることを確認します( https://superuser.com/a/106363/70324 )。
ほぼ同じスクリプトを使用して、すでにコピーされている(ただし、名前が変更されている可能性がある)ファイルをチェックします。このコードは、ファイルの名前のみが異なり、内容は異なることを前提としています。作成時間とは異なり、ファイルを新しいパスにコピーした後でも、通常、最終編集時間は同じままです。コンテンツが異なる場合、私のソリューションはひどく失敗します-ファイルの異なる一意の属性を使用するか(しかしどれですか?)、または次のように述べることができます。新しいファイルを削除する必要があるファイルよりも小さいか古いファイル(編集時間を考慮して)のみ。
スクリプトの機能:
rmlint は、必要なことを正確に実行するためのオプションを備えたコマンドラインユーティリティです。 LinuxとmacOSで動作します。必要なコマンドは次のとおりです。
$ rmlint --progress \
--must-match-tagged --keep-all-tagged \
/mnt/OldDisk1 /mnt/OldDisk2 // /mnt/NewHugeDisk
これにより、必要な重複が見つかります。それらを直接削除する代わりに、シェルスクリプト(./rmlint.sh)を作成します。このスクリプトを確認し、オプションで編集してから実行すると、目的の削除を実行できます。
'--progress'オプションは、Niceの進行状況インジケーターを提供します。 '//'は、 'タグなし'から 'タグ付き'パスを区切ります。 '//'の後のパスは 'タグ付き'と見なされます。 '--must-match-tagged --keep-all-tagged'は、タグ付きパスにコピーがあるタグなしパス内のファイルのみを検索することを意味します。
オプションの短い形式を使用して、そのコマンドを短縮することもできます。
rmlint -g -m -k /mnt/OldDisk1 /mnt/OldDisk2 // /mnt/NewHugeDisk
サードパーティの重複排除ソフトウェアを使用してみましたか?
私はcloudberry deduplicationを試しましたが、次のように非常に効率的です。