
매우 큰 파일(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
— 임시 파일이 아닌 기존 파일을 업데이트합니다. 그러면 원본 파일이 대체됩니다. 200GB 임시 파일을 확보하지 않아도 됩니다. 또한 부분 파일을 의미하므로-P
부분적으로 중복됩니다.
참고: 원래 전송을 어떻게 했는지는 잘 모르겠지만 sftp/scp라면 뭔가 매우 잘못된 것입니다. 네트워크 손상으로부터 완전히 보호하는 것입니다. 반드시 원인을 추적해야 합니다. RAM 결함은 상대적으로 흔한 현상입니다.
답변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