Подтвердить что ты не робот

Как сравнить два содержимого tarball

Я хочу сказать, содержат ли два файла tarball одинаковые файлы с точки зрения имени файла и содержимого файла, не включая метаданные, такие как дата, пользователь, группа.

Однако существуют некоторые ограничения: во-первых, я не контролирую, включены ли метаданные при создании tar файла, на самом деле tar файл всегда содержит метаданные, поэтому напрямую различаются два файла tar, которые не работают. Во-вторых, поскольку некоторые tar файлы настолько велики, что я не могу позволить их развязать в каталог temp и разделить содержащиеся файлы один за другим. (Я знаю, могу ли я распаковать файл file1.tar в файл1/, я могу сравнить их, вызывая "tar -dvf file2.tar" в файле /. Но обычно я не могу позволить себе разорвать хотя бы один из них)

Любая идея, как я могу сравнить два файла tar? Было бы лучше, если бы это можно было выполнить в сценариях SHELL. В качестве альтернативы, есть ли способ получить каждую контрольную сумму подфайла без фактического удаления tarball?

Спасибо,

4b9b3361

Ответ 1

tarsum - это почти то, что вам нужно. Возьмите его вывод, запустите его через сортировку, чтобы получить порядок на каждом из них, а затем сравните два с diff. Это должно привести к тому, что вы выполните базовую реализацию, и было бы достаточно просто выполнить эти шаги в основной программе, изменив код Python, чтобы выполнить всю работу.

Ответ 2

Вы контролируете создание этих tar файлов?
Если это так, лучшим трюком было бы создание контрольной суммы MD5 и сохранение ее в файле внутри самого архива. Затем, когда вы хотите сравнить два файла, вы просто извлекаете эти файлы контрольной суммы и сравниваете их.


Если вы можете позволить себе извлечь только один файл tar, , вы можете использовать опцию --diff tar, чтобы искать различия с содержимым другого tar файл.


Еще один грубый трюк, если у вас все в порядке, просто сравнение имен файлов и их размеров.
Помните, что это не гарантирует, что другие файлы одинаковы!

выполните tar tvf, чтобы просмотреть содержимое каждого файла и сохранить выходы в двух разных файлах. затем, вырезать все, кроме столбцов имени и размера. Предпочтительно сортировать и два файла. Затем просто выполните файл diff между двумя списками.

Просто помните, что эта последняя схема действительно не выполняет контрольную сумму.

Пример tar и вывода (в этом примере все файлы имеют нулевой размер).

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

Вы можете взять два таких отсортированных списка и разделить их.
Вы также можете использовать столбцы даты и времени, если это работает для вас.

Ответ 3

Я понимаю, что это поздний ответ, но я наткнулся на поток, пытаясь добиться того же. Решение, которое я реализовал, выводит tar в stdout и передает его на любой хэш, который вы выберете:

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

Обратите внимание, что порядок аргументов важен; особенно O, который сигнализирует об использовании стандартного вывода.

Ответ 4

Попробуйте pkgdiff, чтобы визуализировать различия между пакетами (обнаруживает добавленные/удаленные/переименованные файлы и измененный контент, существуют с нулевым кодом, если без изменений):

pkgdiff PKG-0.tgz PKG-1.tgz

введите описание изображения здесь

введите описание изображения здесь

Ответ 5

Вот мой вариант, он также проверяет разрешение unix:

Работает только в том случае, если имена файлов короче 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)

Ответ 6

Является tardiff что вы ищете? Это "простой perl script", который "сравнивает содержимое двух архивов и отчетов о любых различиях, найденных между ними".

Ответ 7

Если вы не извлекаете архивы и не нуждаетесь в различиях, попробуйте diff -q:

diff -q 1.tar 2.tar

Этот тихий результат будет "1.tar 2.tar differ" или ничего, если нет различий.

Ответ 8

Существует инструмент под названием archdiff. Это, в основном, perl script, который может просматривать архивы.

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

Ответ 9

У меня есть аналогичный вопрос, и я разрешаю его с помощью python, вот код. ps: хотя этот код используется для сравнения двух содержимого 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")

Ответ 10

Можно использовать простой script:

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

tar1=$1
tar2=$2
shift 2
tar_opts=("[email protected]")

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]