
非常に大きなファイル (200GB) があります。どうやら転送時に正しくコピーされなかったようです。両方の sha1 ハッシュが異なります。ファイルをブロック (1MB や 64MB など) に分割し、各ブロックのハッシュを出力する方法はありますか? その後、比較/修正できますか?
それを実行するための簡単なアプリを書くかもしれません。
答え1
その「クイック アプリ」はすでに存在し、比較的よく使われているのが rsync です。もちろん、rsync はそれ以上のことを行いますが、必要なのは非常にシンプルです。
rsync -cvP --inplace user@source:src-path-to-file dest-path-to-file # from the destination
rsync -cvP --inplace src-path-to-file user@dest:dest-path-to-file # from the source
デフォルトでは、ssh (または、非常に古いバージョンでは rsh) を使用して接続し、データを転送します。他の方法も可能です。
私が合格したオプションは次のとおりです:
-c
— ファイル サイズ/mtime ではなく、チェックサムに基づいてスキップします。デフォルトでは、rsync はサイズと mtime が一致する転送を最適化してスキップします。-c
チェックサムの計算を強制します (これは I/O の観点からはコストのかかる操作です)。これはブロック ベースのチェックサムであり (ファイル全体のみを実行するように指示しない限り)、破損したブロックのみが転送されることに注意してください。ブロック サイズは自動的に選択されますが、上書きできます-B
(上書きする理由はないと思います)。-v
— 詳細、詳細を表示します(どのファイルを処理しているか)-P
— 部分的なファイル (途中まで進んだ場合でも作業が破棄されない) と進行状況バーの両方をオンにします。--inplace
— 一時ファイルではなく、既存のファイルを更新します (一時ファイルは元のファイルを置き換えます)。200 GB の一時ファイルを持つことがなくなります。部分的なファイルも含まれるため、-P
部分的に冗長になります。
ところで、元の転送をどのように行ったかはわかりませんが、sftp/scp だった場合は、何かが間違っています。これらはネットワーク上の破損から完全に保護します。原因を突き止める必要があります。RAM の欠陥は比較的よくある原因です。
答え2
ネットワーク接続を介してファイルを別のマシンに再転送する場合は、rsyncを使用する。
どこに違いがあるのかを知りたい場合、最も簡単な方法は、同じマシンに 2 つのバージョンをインストールすることです。帯域幅が高すぎるためにこれをしたくない場合は、ファイルのチャンクをチェックする方法があります。
このメソッドは、head -c
ファイルの位置を中断した場所に残すことに依存し、ループを終了する場所を知るためにサイズを事前に計算します。
n=$(($(wc -c <very_large_file) / (64*1024*1024) + 1))
i=0
while [ $i -gt $n ]; do
head -c 64m | sha256sum
i=$((i+1))
done <very_large_file
このメソッドは、head -c
ファイルの位置を中断した場所に残し、cksum
各チャンクのサイズを見つけるために使用します (短いチャンクはファイルの終わりを示します)。
while true; do
output=$(head -c 64m | cksum)
size=${output#* }; size=${output%% *}
if [ $size -eq 0 ]; then break; fi
echo "$output"
done <very_large_file
このメソッドは、dd
各チャンクの目的の開始位置にスキップするために呼び出します。
n=$(($(wc -c <very_large_file) / (64*1024*1024) + 1))
i=0
while [ $i -gt $n ]; do
dd if=very_large_file ibs=64m skip=$i count=1 | sha256sum
i=$((i+1))
done <very_large_file