非常に大きなファイル(200GB)があります。どうやら私がそれを転送したとき、それは正しくコピーされませんでした。両方のsha1ハッシュは異なります。ファイルをブロック(1MBや64MBなど)に分割し、各ブロックのハッシュを出力する方法はありますか?次に、比較/修正しますか?
私はそれを行うための簡単なアプリを書くかもしれません。
その「クイックアプリ」はすでに存在し、比較的一般的です: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
—一時ファイルではなく、既存のファイルを更新します(一時ファイルは元のファイルを置き換えます)。 200GBの一時ファイルを用意する必要がありません。また、部分的なファイルを意味するため、-P
は部分的に冗長です。ところで:元の転送をどのように行ったかはわかりませんが、sftp/scpの場合は、何かが非常に間違っています。ネットワークの破損から完全に保護されています。あなたは本当に原因を突き止める必要があります。欠陥RAMは比較的一般的なものです。
ネットワーク接続を介してファイルを別のマシンに再転送する場合は、 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