두 개의 zip으로 압축 된 파일이 같은지 어떻게 확인할 수 있습니까? 디렉토리를 만듭니다. 일부 데이터를

단순히 텍스트 파일로 데이터를 덤프하여 “멍청한”백업을 수행하는 동안 공간을 절약하려고합니다. 내 백업 스크립트는 매일 실행되며 다음과 같습니다.

  1. 백업 날짜를 따서 명명 된 디렉토리를 만듭니다.
  2. 일부 데이터를 텍스트 파일로 덤프하십시오 "$name".
  3. 파일이 유효하면 gzip으로 압축하십시오 gzip "$name". 그렇지 않으면 rm "$name".

이제 전날에도 동일한 데이터를 사용할 수있는 경우 파일을 제거하는 추가 단계를 추가하고 싶습니다 (그리고 심볼릭 링크 또는 하드 링크를 만듭니다).

처음에는을 사용하려고 생각 md5sum "$name"했지만 파일 이름과 생성 날짜도 저장하기 때문에 작동하지 않습니다.

않습니다 gzip이 개 gzip으로 압축 된 파일을 비교하고 같은지 여부 말해 할 수있는 옵션이? 경우 gzip이러한 옵션이 없습니다, 내 목표를 달성하기위한 또 다른 방법은 무엇입니까?



답변

그의 의견 (또는 Kevin의 명령, 비슷한)에서 mreithub이 제안한대로 zcmp또는 zdiff을 사용할 수 있습니다 . 이들은 실제로 두 파일의 압축을 풀고 cmp또는 로 전달하기 때문에 상대적으로 비효율적 diff입니다. “동일하다”라고 대답하고 싶다면 cmp훨씬 더 빠를 것입니다.

의 접근 방식 md5sum은 완벽하지만 실행 하기 전에 MD5를 가져와야 합니다 gzip. 그런 다음 결과 .gz파일 과 함께 파일에 저장 하십시오. 그런 다음 압축하기 전에 파일을 쉽게 비교할 수 있습니다. 이름이 같으면 md5sum -c이 작업을 수행합니다.

$ mkdir "backup1"
$ cd backup1
$ echo "test" > backup-file
$ md5sum backup-file > backup-file.md5
$ gzip -9 backup-file

그리고 다음 백업 :

$ mkdir "backup2"
$ cd backup2
$ echo "test" > backup-file
$ md5sum -c ../backup1/backup-file.md5
backup-file: OK

따라서 변경되지 않았습니다. OTOH, 바뀌었다 :

$ echo "different" > backup-file
$ md5sum -c ../backup1/backup-file.md5
backup-file: FAILED
md5sum: WARNING: 1 computed checksum did NOT match

전달 --quiet하면 종료 코드 만 제공됩니다. 일치하는 경우 0, 차이가없는 경우 0

MD5는 상당히 빠르지 만 굉장히 빠르지는 않습니다. MD4 ( openssl md4명령 줄에서 얻는 것이 가장 좋습니다)는 약 두 배 빠릅니다 (MD5도 안전하지는 않지만 아무도 파괴하려고 시도하지 않을 때 충돌에 약합니다). SHA-1 ( sha1sum)이 더 안전하지만 느립니다. SHA-256 ( sha256sum)은 안전하지만 여전히 느립니다. CRC32는 몇 배 빨라야하지만 더 짧아서 더 많은 랜덤 충돌이 발생합니다. 또한 완전히 안전하지 않습니다.


답변

@derobert 의 답변은 훌륭하지만 내가 찾은 다른 정보를 공유하고 싶습니다.

gzip -l -v

gzip 압축 파일에는 이미 해시가 포함되어 있습니다 (안전하지는 않지만 이 SO post 참조 ).

$ echo something > foo
$ gzip foo
$ gzip -v -l foo.gz
method  crc     date  time           compressed        uncompressed  ratio uncompressed_name
defla 18b1f736 Feb  8 22:34                  34                  10 -20.0% foo

CRC와 압축되지 않은 크기를 결합하여 빠른 지문을 얻을 수 있습니다.

gzip -v -l foo.gz | awk '{print $2, $7}'

cmp

두 바이트가 같은지 여부를 확인하려면을 사용하십시오 cmp file1 file2. 이제 gzip으로 압축 된 파일에는 데이터 및 바닥 글 (CRC + 원본 크기)이 추가 된 헤더가 있습니다. GZIP 파일 포맷의 설명 헤더 파일을 압축하고, 파일명은 10 바이트의 헤더 뒤에 첨부되는 문자열 NUL 종료되는 시간을 포함 보여준다.

따라서 파일 이름이 일정하고 동일한 명령 ( gzip "$name")이 사용되면 cmp시간을 포함하여 첫 번째 바이트를 사용 하고 건너 뛰어 두 파일이 다른지 여부를 확인할 수 있습니다 .

cmp -i 8 file1 file2

참고 : 동일한 압축 옵션이 중요하다는 가정하에 그렇지 않으면 명령은 항상 파일을 다른 것으로보고합니다. 이는 압축 옵션이 헤더에 저장되어 압축 된 데이터에 영향을 줄 수 있기 때문에 발생합니다. cmp원시 바이트 만보고 gzip으로 해석하지 않습니다.

길이가 같은 파일 이름이 있으면 파일 이름을 읽은 후 건너 뛸 바이트를 계산할 수 있습니다. 파일 이름의 크기가 다른 cmp경우와 같이 바이트를 건너 뛴 후 실행할 수 있습니다 cmp <(cut -b9- file1) <(cut -b10- file2).

zcmp

이것은 가장 좋은 방법입니다. 먼저 데이터를 압축하고 바이트를 비교하기 시작합니다 cmp(실제로 zcmp( zdiff) 셸 스크립트 에서 수행되는 작업입니다 ).

한 가지 참고 사항은 매뉴얼 페이지의 다음 참고 사항을 두려워하지 마십시오.

비교하기 전에 두 파일을 모두 압축 해제해야하는 경우 두 번째 파일은 / tmp로 압축 해제됩니다. 다른 모든 경우 zdiff 및 zcmp는 파이프 만 사용합니다.

충분히 새로운 Bash가 있으면 압축은 임시 파일을 사용하지 않고 파이프 만 사용합니다. 또는 zdiff출처에서 알 수 있듯이

# Reject Solaris 8's buggy /bin/bash 2.03.


답변

두 개의 gzip 파일을 비교하려면 내용, 하나의 명령, no diff만 비교하십시오.md5sum

$ diff -q <(zcat one.gz|md5sum|cut -f1 -d' ') \
          <(zcat two.gz|md5sum|cut -f1 -d' ') \
    && echo same || echo not_same

관련 차이점을 ‘필터링’할 수도 있습니다.

$ diff -q <(zcat one.gz|grep -v '^-- Dump completed'|md5sum|cut -f1 -d' ') \
          <(zcat two.gz|grep -v '^-- Dump completed'|md5sum|cut -f1 -d' ') \
   && echo same || echo not_same

스크립팅의 경우 필터 기능 (테스트되지 않은 예제)을 권장합니다.

do_filter_sum() {
  zcat $1 | grep -v '^-- Dump completed' | md5sum | cut -f1 -d' '
}

diff -q <(do_filter_sum one.gz) \
        <(do_filter_sum two.gz) \
        && echo same || echo not_same


답변