Как сравнить два содержимого tarball
Я хочу сказать, содержат ли два файла tarball одинаковые файлы с точки зрения имени файла и содержимого файла, не включая метаданные, такие как дата, пользователь, группа.
Однако существуют некоторые ограничения:
во-первых, я не контролирую, включены ли метаданные при создании tar файла, на самом деле tar файл всегда содержит метаданные, поэтому напрямую различаются два файла tar, которые не работают.
Во-вторых, поскольку некоторые tar файлы настолько велики, что я не могу позволить их развязать в каталог temp и разделить содержащиеся файлы один за другим. (Я знаю, могу ли я распаковать файл file1.tar в файл1/, я могу сравнить их, вызывая "tar -dvf file2.tar" в файле /. Но обычно я не могу позволить себе разорвать хотя бы один из них)
Любая идея, как я могу сравнить два файла tar? Было бы лучше, если бы это можно было выполнить в сценариях SHELL. В качестве альтернативы, есть ли способ получить каждую контрольную сумму подфайла без фактического удаления tarball?
Спасибо,
Ответы
Ответ 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]