문제

날짜, 사용자, 그룹과 같은 메타 데이터를 포함하지 않고 파일 이름 및 파일 컨텐츠 측면에서 두 개의 Tarball 파일에 동일한 파일이 포함되어 있는지 여부를 알려 드리고자합니다.

그러나 몇 가지 제한 사항이 있습니다. 첫째, TAR 파일을 만들 때 메타 데이터가 포함되어 있는지 여부를 제어 할 수 없습니다. 실제로 TAR 파일에는 항상 메타 데이터가 포함되어 있으므로 두 개의 TAR 파일이 직접 다르게 작동하지 않습니다. 둘째, 일부 TAR 파일이 너무 커서 임시 디렉토리에 투자 할 여유가없고 포함 된 파일을 하나씩 차단할 수 없습니다. (파일 1.tar를 file1/, 파일에서 'tar -dvf file2.tar'를 호출하여 비교할 수 있는지 알고 있습니다.

두 개의 TAR 파일을 어떻게 비교할 수 있는지 아십니까? 쉘 스크립트 내에서 달성 할 수 있다면 더 나을 것입니다. 또는 실제로 Tarball을 사용하지 않고 각 하위 파일의 체크섬을 얻는 방법이 있습니까?

감사,

도움이 되었습니까?

해결책

타르섬 거의 필요한 것입니다. 출력을 취하고 정렬을 통해 실행하여 순서를 각각 동일하게 한 다음 두와 Diff와 비교하십시오. 이를 통해 기본 구현이 진행되며 전체 작업을 수행하기 위해 Python 코드를 수정하여 이러한 단계를 메인 프로그램으로 쉽게 가져 오기에 충분할 것입니다.

다른 팁

이 TAR 파일의 생성을 제어하고 있습니까?
그렇다면 가장 좋은 요령은 MD5 체크섬을 만들고 파일에 저장하는 것입니다. 아카이브 자체 내에서. 그런 다음 두 파일을 비교하려면이 체크섬 파일을 추출하여 비교합니다.


감당할 수 있다면 하나의 타르 파일 만 추출하십시오, 당신은 사용할 수 있습니다 --diff 옵션 tar 다른 TAR 파일의 내용과 차이점을 찾기 위해.


하나 더 조잡한 트릭 당신이 그냥 괜찮다면 파일 이름과 크기의 비교.
다른 파일이 동일하다는 것을 보장하지는 않습니다!

실행 a tar tvf 각 파일의 내용을 나열하고 출력을 서로 다른 파일에 저장합니다. 그런 다음 파일 이름과 크기 열 외에 모든 것을 자릅니다. 바람직하게는 두 파일도 정렬하십시오. 그런 다음 두 목록 사이에 파일 차이 만 수행하십시오.

이 마지막 체계는 실제로 체크섬을 수행하지 않는다는 것을 기억하십시오.

샘플 타르 및 출력 (이 예에서는 모든 파일이 제로 크기입니다).

$ tar tvfj pack1.tar.bz2
drwxr-xr-x user/group 0 2009-06-23 10:29:51 dir1/
-rw-r--r-- user/group 0 2009-06-23 10:29:50 dir1/file1
-rw-r--r-- user/group 0 2009-06-23 10:29:51 dir1/file2
drwxr-xr-x user/group 0 2009-06-23 10:29:59 dir2/
-rw-r--r-- user/group 0 2009-06-23 10:29:57 dir2/file1
-rw-r--r-- user/group 0 2009-06-23 10:29:59 dir2/file3
drwxr-xr-x user/group 0 2009-06-23 10:29:45 dir3/

정렬 된 이름/크기 목록을 생성하도록 명령

$ tar tvfj pack1.tar.bz2 | awk '{printf "%10s %s\n",$3,$6}' | sort -k 2
0 dir1/
0 dir1/file1
0 dir1/file2
0 dir2/
0 dir2/file1
0 dir2/file3
0 dir3/

정렬 된 두 개의 목록을 가져 와서 차별 할 수 있습니다.
날짜 및 시간 열을 사용할 수도 있습니다.

또한 시도하십시오 pkgdiff 패키지 간의 차이를 시각화하려면 (추가/제거/이름이 변경되고 변경된 컨텐츠가 변경되지 않은 경우 제로 코드로 존재합니다) :

pkgdiff PKG-0.tgz PKG-1.tgz

enter image description here

enter image description here

여기 내 변형이 있습니다. 유닉스 허가도 확인하고 있습니다.

파일 이름이 200 Char보다 짧은 경우에만 작동합니다.

diff <(tar -tvf 1.tar | awk '{printf "%10s %200s %10s\n",$3,$6,$1}'|sort -k2) <(tar -tvf 2.tar|awk '{printf "%10s %200s %10s\n",$3,$6,$1}'|sort -k2)

나는 이것이 늦은 답변이라는 것을 알고 있지만, 같은 일을하려고 시도하면서 실을 만났다. 내가 구현 한 솔루션은 타르를 stdout으로 출력하고 선택한 해시에 파이프합니다.

tar -xOzf archive.tar.gz | sort | sha1sum

논쟁의 순서가 중요하다는 점에 유의하십시오. 특히 O stdout을 사용하는 신호.

~이다 타르 디프 무엇을 찾고 있습니까? "간단한 Perl 스크립트"로 "두 개의 타르 볼의 내용을 비교하고 그 사이에 발견 된 차이점에 대한 보고서"입니다.

아카이브를 추출하지 않거나 차이가 필요하지 않으면 시도하십시오. 차이'에스 -큐 옵션:

diff -q 1.tar 2.tar

이것 조용한 결과가 될 것입니다 "1.TAR 2.TAR DIFER" 또는 차이가 없다면 아무것도 없습니다.

도구가 호출됩니다 Archdiff. 기본적으로 아카이브를 살펴볼 수있는 Perl 스크립트입니다.

Takes two archives, or an archive and a directory and shows a summary of the
differences between them.

비슷한 질문이 있고 파이썬으로 해결합니다. 여기 코드가 있습니다. 추신 :이 코드는 두 개의 Zipball의 내용을 비교하는 데 사용되지만 Tarball과 비슷하지만 도와 드릴 수 있기를 바랍니다.

import zipfile
import os,md5
import hashlib
import shutil

def decompressZip(zipName, dirName):
    try:
        zipFile = zipfile.ZipFile(zipName, "r")
        fileNames = zipFile.namelist()
        for file in fileNames:
            zipFile.extract(file, dirName)
        zipFile.close()
        return fileNames
    except Exception,e:
        raise Exception,e

def md5sum(filename):
    f = open(filename,"rb")
    md5obj = hashlib.md5()
    md5obj.update(f.read())
    hash = md5obj.hexdigest()
    f.close()
    return str(hash).upper()

if __name__ == "__main__":
    oldFileList = decompressZip("./old.zip", "./oldDir")
    newFileList = decompressZip("./new.zip", "./newDir")

    oldDict = dict()
    newDict = dict()

    for oldFile in oldFileList:
        tmpOldFile = "./oldDir/" + oldFile
        if not os.path.isdir(tmpOldFile):
            oldFileMD5 = md5sum(tmpOldFile)
            oldDict[oldFile] = oldFileMD5

    for newFile in newFileList:
        tmpNewFile = "./newDir/" + newFile
        if not os.path.isdir(tmpNewFile):
            newFileMD5 = md5sum(tmpNewFile)
            newDict[newFile] = newFileMD5

    additionList = list()
    modifyList = list()

    for key in newDict:
        if not oldDict.has_key(key):
            additionList.append(key)
        else:
            newMD5 = newDict[key]
            oldMD5 = oldDict[key]
            if not newMD5 == oldMD5:
            modifyList.append(key)

    print "new file lis:%s" % additionList
    print "modified file list:%s" % modifyList

    shutil.rmtree("./oldDir")
    shutil.rmtree("./newDir")

도 있습니다 확산, 이는 더 일반적이며 재귀 적으로 사물을 비교할 수 있습니다 (다양한 형식 포함).

pip install diffoscope

간단한 스크립트를 사용할 수 있습니다.

#!/usr/bin/env bash
set -eu

tar1=$1
tar2=$2
shift 2
tar_opts=("$@")

tmp1=`mktemp -d`
_trap="rm -r "$tmp1"; ${_trap:-}" && trap "$_trap" EXIT
tar xf "$tar1" -C "$tmp1"

tmp2=`mktemp -d`
_trap="rm -r "$tmp2"; ${_trap:-}" && trap "$_trap" EXIT
tar xf "$tar2" -C "$tmp2"

diff -ur "${tar_opts[@]:+${tar_opts[@]}}" "$tmp1" "$tmp2"

용법:

diff-tars.sh TAR1 TAR2 [DIFF_OPTS]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top