Comment comparer le contenu de deux archives
-
06-07-2019 - |
Question
Je veux savoir si deux fichiers tarball contiennent des fichiers identiques, en termes de nom de fichier et de contenu de fichier, à l'exclusion des métadonnées telles que la date, l'utilisateur et le groupe.
Cependant, il existe certaines restrictions: Tout d'abord, je n'ai aucun contrôle sur l'inclusion ou non des métadonnées dans le fichier tar. En fait, le fichier tar contient toujours des méta-données. Par conséquent, les deux fichiers tar diff ne fonctionnent pas directement. Deuxièmement, étant donné que certains fichiers tar sont si volumineux, je ne peux pas me permettre de les décompresser dans un répertoire temporaire et de les comparer un par un. (Je sais que si je peux décompresser fichier1.tar dans fichier1 /, je peux les comparer en invoquant 'tar -dvf fichier2.tar' dans fichier /. Mais en général, je ne peux pas me permettre de décompresser, même l'un d'eux.
Avez-vous une idée de la façon dont je peux comparer les deux fichiers tar? Ce serait mieux si cela pouvait être accompli dans les scripts SHELL. Sinon, y a-t-il un moyen d’obtenir la somme de contrôle de chaque sous-fichier sans réellement décompresser une archive?
Merci,
La solution
tarsum est presque ce dont vous avez besoin. Prenez sa sortie, faites-la trier pour que l'ordre soit identique sur chacun, puis comparez les deux avec diff. Cela devrait vous permettre d’obtenir une implémentation de base, et il serait assez facile d’insérer ces étapes dans le programme principal en modifiant le code Python pour qu’il fasse tout le travail.
Autres conseils
Contrôlez-vous la création de ces fichiers tar?
Si tel est le cas, le meilleur truc serait de créer une somme de contrôle MD5 et de la stocker dans un fichier au sein de l’archive elle-même. Ensuite, lorsque vous souhaitez comparer deux fichiers, il vous suffit d'extraire ces fichiers de somme de contrôle et de les comparer.
Si vous pouvez vous permettre de extraire un seul fichier tar , vous pouvez utiliser l'option - diff
de tar
rechercher des différences avec le contenu d’un autre fichier tar.
Encore un truc brutal si tout va bien avec seulement une comparaison des noms de fichiers et de leur taille .
Rappelez-vous, cela ne garantit pas que les autres fichiers sont identiques!
exécutez un tar tvf
pour répertorier le contenu de chaque fichier et stocker les sorties dans deux fichiers différents. Ensuite, découpez tout ce qui est en dehors des colonnes de nom de fichier et de taille. De préférence, triez également les deux fichiers. Ensuite, faites juste un diff de fichier entre les deux listes.
N'oubliez pas que ce dernier schéma ne fait pas vraiment de somme de contrôle.
Exemple de tar et de sortie (tous les fichiers sont de taille zéro dans cet exemple).
$ 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/
Commande permettant de générer une liste de noms / tailles triés
$ 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/
Vous pouvez prendre deux listes triées et les comparer.
Vous pouvez également utiliser les colonnes de date et d’heure si cela vous convient.
Essayez également de pkgdiff pour visualiser les différences entre les packages (détecte les fichiers ajoutés / supprimés / renommés et le contenu modifié), existe avec le code zéro si inchangé):
pkgdiff PKG-0.tgz PKG-1.tgz
Voici ma variante, elle vérifie également l'autorisation Unix:
Ne fonctionne que si les noms de fichiers ont moins de 200 caractères.
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)
Je me rends compte que la réponse est tardive, mais je suis tombé sur le fil alors que je tentais de faire la même chose. La solution que j'ai mise en œuvre génère le fichier tar vers stdout et le dirige vers le hachage de votre choix:
tar -xOzf archive.tar.gz | sort | sha1sum
Notez que l'ordre des arguments est important. en particulier O
qui signale l’utilisation de stdout.
tardiff correspond-il à ce que vous recherchez? C’est un "simple script Perl" qui "compare le contenu de deux archives tarball et signale toute différence constatée entre elles".
Si vous ne voulez pas extraire les archives ni avoir besoin des différences, essayez diff . L'option -q de:
diff -q 1.tar 2.tar
Ce résultat silencieux sera "1.tar 2.tar different" ou rien, s'il n'y a pas de différence.
Il existe un outil appelé archdiff . Il s’agit essentiellement d’un script Perl permettant de consulter les archives.
Takes two archives, or an archive and a directory and shows a summary of the
differences between them.
J'ai une question similaire que je résous en python, voici le code. ps: bien que ce code soit utilisé pour comparer le contenu de deux zipball, mais il est similaire à tarball, j'espère pouvoir vous aider
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")
Il existe également un diffoscope , plus générique, qui permet de comparer des éléments de manière récursive (y compris divers formats).
pip install diffoscope
On peut utiliser un script simple:
#!/usr/bin/env bash
set -eu
tar1=$1
tar2=$2
shift 2
tar_opts=("$@")
tmp1=`mktemp -d`
_trap="rm -r "$tmp1"; ${_trap:-}" && trap " On peut utiliser un script simple:
diff-tars.sh TAR1 TAR2 [DIFF_OPTS]
Utilisation:
<*>trap" EXIT
tar xf "$tar1" -C "$tmp1"
tmp2=`mktemp -d`
_trap="rm -r "$tmp2"; ${_trap:-}" && trap " On peut utiliser un script simple:
<*>
Utilisation:
<*>trap" EXIT
tar xf "$tar2" -C "$tmp2"
diff -ur "${tar_opts[@]:+${tar_opts[@]}}" "$tmp1" "$tmp2"
Utilisation:
<*>