매우 큰 파일(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
— 파일 크기/런타임이 아닌 체크섬을 기준으로 건너뜁니다. 기본적으로 rsync는 크기 및 런타임과 일치하는 전송을 최적화하고 건너뜁니다.-c
강제로 체크섬을 계산합니다(I/O 측면에서 비용이 많이 드는 작업). 이는 블록 기반 체크섬이며(전체 파일만 수행하도록 지시하지 않는 한) 손상된 블록만 전송합니다. 블록 크기는 자동으로 선택되지만 재정의될 수 있습니다-B
(그렇게 할 이유가 있는지 의심스럽습니다).-v
— Verbose는 몇 가지 세부 정보(처리 중인 파일)를 제공합니다.-P
— 두 개의 부분 파일(중간 작업이 완료되어도 작업을 포기하지 않도록)과 진행률 표시줄을 엽니다.--inplace
— 임시 파일이 아닌 기존 파일을 업데이트합니다. 그러면 원본 파일이 대체됩니다. 200GB의 임시 파일을 확보하지 않아도 됩니다. 또한 부분 파일을 의미하므로-P
부분적으로 중복됩니다.
참고: 원시 전송을 어떻게 수행하고 있는지 잘 모르겠지만 sftp/scp라면 뭔가 크게 잘못된 것입니다. 네트워크의 손상을 완전히 방지합니다. 정말로 그 이유를 알아내야 합니다. RAM 결함은 비교적 흔히 발생합니다.
답변2
네트워크 연결을 통해 파일을 다른 기기로 다시 전송하려면,rsync 사용.
차이점이 무엇인지 확인하려는 경우 가장 쉬운 방법은 동일한 컴퓨터에 두 버전을 모두 설치하는 것입니다. 대역폭이 너무 비싸서 이를 원하지 않는 경우 파일 블록을 확인하는 방법은 다음과 같습니다.
이 방법은 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