Pergunta

Eu quero dizer se dois arquivos tarball contêm arquivos idênticos, em termos de nome de arquivo e conteúdo do arquivo, não incluindo meta-dados, como data, usuário, grupo.

No entanto, existem algumas restrições: em primeiro lugar, eu não tenho controle sobre se a meta-dados são incluídos ao fazer o arquivo tar, na verdade, o arquivo tar sempre contém meta-dados, diff tão diretamente os dois arquivos de alcatrão não funciona. Em segundo lugar, uma vez que alguns arquivos tar são tão grandes que eu não posso dar ao luxo de descompactar-los em um diretório temporário e diff os arquivos contidos um por um. (Eu sei se eu posso file1.tar untar em file1 /, posso compará-los invocando 'tar -dvf file2.tar' no arquivo /. Mas normalmente eu não posso pagar untar até mesmo um deles)

Qualquer idéia de como posso comparar os dois arquivos tar? Seria melhor se ele pode ser realizado dentro de scripts shell. Como alternativa, há alguma maneira de obter soma de verificação de cada sub-arquivo sem um tarball realmente untar?

Obrigado,

Foi útil?

Solução

tarsum é quase o que você precisa. Tome a sua saída, executá-lo através tipo de obter a ordenação idêntica em cada um, e então comparar os dois com diff. Isso deve te dar uma implementação básica indo, e seria facilmente o suficiente para puxar esses passos para o programa principal, modificando o código Python para fazer todo o trabalho.

Outras dicas

Você controla a criação desses arquivos tar?
Se assim for, o melhor truque seria a criação de um MD5 checksum e armazená-lo em um arquivo dentro do próprio arquivo. Então, quando você quiser comparar dois arquivos, você acabou de extrair estes arquivos de checksum e compará-los.


Se você pode dar ao luxo de extrato de apenas um arquivo tar , você pode usar a opção --diff de tar para procurar diferenças com o conteúdo de outro arquivo tar.


Um truque mais bruto se você está bem com apenas um a comparação dos nomes dos arquivos e seus tamanhos .
Lembre-se, isso não garante que os outros arquivos são os mesmos!

executar um tar tvf para listar o conteúdo de cada arquivo e armazenar as saídas em dois arquivos diferentes. em seguida, fatia para fora tudo além das colunas de nome de arquivo e tamanho. De preferência, tipo os dois arquivos também. Então, basta fazer uma diff arquivo entre as duas listas.

Apenas lembre-se que este último regime não realmente soma de verificação.

tar amostra e saída (todos os arquivos são de tamanho zero neste exemplo).

$ 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/

comando para gerar nome ordenada / list tamanho

$ 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/

Você pode tomar duas dessas listas ordenadas e diff-los.
Você também pode usar os de data e hora colunas se isso funciona para você.

pkgdiff para visualizar as diferenças entre pacotes (detecta adicionadas / removidas / arquivos renomeados e conteúdo alterado, existir com código zero se inalterado):

pkgdiff PKG-0.tgz PKG-1.tgz

 enter descrição da imagem aqui

 enter descrição da imagem aqui

Aqui está a minha variante, está verificando a permissão unix demasiado:

só funciona se os nomes de arquivos são mais curtos do que 200 caracteres.

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)

Eu percebo que esta é uma resposta tardia, mas me deparei com o fio enquanto tenta conseguir a mesma coisa. A solução que eu tenho implementado saídas do tar para stdout, e tubos para qualquer hash de que você escolher:

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

Note que a ordem dos argumentos é importante; particularmente O qual os sinais de uso stdout.

Tardiff o que você está procurando? É "um script Perl simples" que "compara o conteúdo de dois tarballs e relatórios sobre eventuais diferenças encontradas entre eles."

Se não extrair os arquivos nem precisar as diferenças, tente diff 's q opção:

diff -q 1.tar 2.tar

Este tranquila resultado será "1.tar 2.tar diferem" ou nada, se há diferenças.

Há ferramenta chamada archdiff . É basicamente um script Perl que pode olhar para os arquivos.

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

Eu tenho uma pergunta semelhante e eu resolvê-lo por python, aqui está o código. ps: embora este código é usado para comparar o conteúdo de dois de zipball, mas é semelhante com tarball, espero que eu possa ajudá-lo

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")

Há também diffoscope é, o que é mais genérico, e permite comparar as coisas de forma recursiva (incluindo vários formatos).

pip install diffoscope

Pode-se usar um script simples:

#!/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"

Uso:

diff-tars.sh TAR1 TAR2 [DIFF_OPTS]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top