チェックサムの違いを維持しながら、1つのフォルダから同じファイルを削除するように2つのフォルダをマージする方法は?

チェックサムの違いを維持しながら、1つのフォルダから同じファイルを削除するように2つのフォルダをマージする方法は?

異なる時点でドライブから回復する必要がある状況があります。このドライブはファイルの存在が異なるだけでなく、いくつかの破損がある可能性があり、その多くは明らかに破損しています。

左フォルダの名前は「A」、右フォルダの名前は「B」です。

私は次のように2つの画像をマージする責任があります。

  1. BにはあるがAにはないすべてのファイルをAに移動する必要があります。
  2. 両方の場所に存在し、同じファイルはすべてBから削除する必要があり、最後に
  3. 異なるチェックサムを持つファイルは B に残る必要があり、A と B の間で異なるファイルを手動で比較できます。ただし、チェックサムが異なるファイル(実際のコンテンツなど)以外は、Bにファイルがあってはなりません。他のコンテンツを維持してください。

ノート:現在の時点では、日付はほとんど重要ではありません。いいねメタデータに前の日付を保持します。

どうすればきれいに処理できますか?残念ながら、数十テラバイトのデータに対してこれを行う必要があるため、これを自動化する方法がわからない場合は、プロセスが非常に長くなります。コンテンツの90〜95%が同じように見えるため、手動比較を準備するには、「設定して忘れてしまう」アプローチを開発する必要があります。

答え1

2段階と3段階が一番難しいようですので、その段階から始めます。

rdfind重複したファイルを見つけるためのツールがあります。重複が検出されたらどうするかを決定します。あなたの場合はBから削除しようとしていますrdfind -deleteduplicates true A B。 AとBに同じファイルがある場合は、Aにファイルを保持します。他のオプションは、コピーをハードリンクまたはソフトリンクに置き換えるか、結果を報告することです。

その後、Bに保存されているファイルは、Bに固有のファイルであるか、BのファイルがAのファイルとは異なります。唯一のファイルをBからA:に移動し、mv -i B/* A/上書きnoするかどうかを尋ねるたびに応答します。自動化を使用してこれを行うことができますyes no | mv -i B/* A/。 GNU mvを使用している場合mv --no-clobber B/* A/

もちろん、実際のデータを使用する前に練習が必要です。 AとBのファイルを指すハードリンクツリーを簡単に作成し、そこでmkdir training; cp -lr A training; cp -lr B training練習することができます。

答え2

方法は簡単ですが、Aに欠落しているファイルが多いと効率が非常に低下します。各ステップに順番に従うだけです。私はディレクトリと通常のファイルだけがあると仮定します(特別なファイルのメタデータを比較することはより多くの作業で行うことができます)。警告:テストされていないコードです。

まず、BにはあるがAにはないファイルをAにコピーします。可能であれば、メタデータ(タイムスタンプ、権限)を保存してください。

rsync -a --ignore-existing B A

次に、Bから重複したアイテムを削除します。この時点で、元のAに存在しなかったファイルは同じです。

cd B
find . -type f -exec sh '
  for x; do
    if cmp -s "$x" "$0/$x"; then rm "$x"; fi
  done
' /path/to/A {} +

(オプション)Bから空のディレクトリを削除します。

find B -depth -type d -exec rmdir {} + 2>/dev/null

ステップ2では、すでにAから欠落しているすべてのファイルがBからコピー、比較、および削除されるため、これは非効率的です。 Aから多くのファイルが欠落している場合は、Bに単一のパスを渡してファイルをAに移動し、重複エントリを削除する方が効率的です。これは、AとBが同じファイルシステムにある場合に特に当てはまります。したがって、ソースをコピーして削除するよりもファイルを移動する方が安いです。

答え3

私はあなたの主張に異議を申し立てることから始めます。あなたはすべてを一段階で処理しようとしています。ファイルの回復を開始する前に、復元されたシステムがどのように見えるかを知ることをお勧めします。

実際、最初に違いを見つけるのは思ったよりも簡単です。

ステップ1

ディスク上の各ファイルのハッシュ値を取得します。何があってもしなければなりません。だからそれを終わらせることをお勧めします。 ハードリンクが多すぎない場合は、次のコマンドがうまく機能します。。ディレクトリの名前がであると/media/A仮定します/media/B

cd /media/A
find . -type f -exec sha256sum {} + > ~/hashes.txt

これにより、ディスク上のすべての一般ファイルのハッシュが生成されます。ファイルがハードリンクされている場合は、各名前の下に表示されます(各名前に対して一度検索されます)。

ステップ2

変更の識別

cd /media/B
sha256sum -c ~/hashes.txt > ~/check.txt

check.txt には 3 種類の行が含まれます。

  • good/file: OK
  • missing/file: FAILED open or read
  • changed/file: FAILED

ステップ3

ショートカットでは、次のコマンドを使用して、欠落しているファイルをすべてコピーできます。

rsync -a --ignore-existing /media/A/ /media/B/

ステップ4

その後、ファイルの変更について心配するだけです。

grep 'FAILED$' ~/check.txt | while read file ; do
    echo "${file%: FAILED}"
done > ~/changed.txt

これにより、各行にファイル名を持つselected.txtが提供されます。それぞれは、両方のシステムで変更されたファイルです。

changed.txtこれで、アーカイブするファイルとBからAで上書きするファイルを並べ替えて決定するのはユーザーの役割です。

答え4

ファイル名に「改行」がないと仮定すると、次のように動作します。

cd B
find . -type f -print | while read f
do
    [[ -f "A/$f" ]] || { echo mv "$f" "A/$f" ; continue; }
    cmp "$f" "A/$f" && echo rm "$f"
done

実行しても問題ない場合は、「echo」という単語を削除して実際のコマンドを実行してください。

関連情報