J'essaie d'économiser de l'espace tout en faisant une sauvegarde "stupide" en déversant simplement les données dans un fichier texte. Mon script de sauvegarde est exécuté quotidiennement et ressemble à ceci:
- Créez un répertoire nommé d'après la date de sauvegarde.
- Vider certaines données dans un fichier texte
"$name"
. - Si le fichier est valide, gzipper:
gzip "$name"
. Dans le cas contraire,rm "$name"
.
Maintenant, je veux ajouter une étape supplémentaire pour supprimer un fichier si les mêmes données étaient également disponibles la veille (et créer un lien symbolique ou un lien physique).
Au début, j'ai pensé à utiliser md5sum "$name"
, mais cela ne fonctionne pas car je stocke également le nom de fichier et la date de création.
A gzip
une option pour comparer deux fichiers compressés et me dire s'ils sont égaux ou non? Si ce gzip
n'est pas le cas, existe-t-il un autre moyen d'atteindre mon objectif?
gzip
file-comparison
Lekensteyn
la source
la source
diff <(zcat file1) <(zcat file2)
, mais la suggestion de mrethub dezdiff
semble beaucoup mieux.Réponses:
Vous pouvez utiliser
zcmp
ouzdiff
comme mreithub le suggère dans son commentaire (ou la commande de Kevin, qui est similaire). Celles-ci seront relativement inefficaces, car elles décompressent les deux fichiers, puis les transmettent àcmp
oudiff
. Si vous voulez juste répondre "sont-ils les mêmes", vous voulezcmp
, ce sera beaucoup plus rapide.Votre approche avec le
md5sum
est parfaitement bonne, mais vous devez prendre le MD5 avant de courirgzip
. Ensuite, stockez-le dans un fichier avec le.gz
fichier résultant . Vous pouvez ensuite comparer facilement le fichier avant de le compresser. Si le nom est le même, lemd5sum -c
fera pour vous.Et la prochaine sauvegarde:
Cela n'a donc pas changé. OTOH, avait-il changé:
Si vous y passez
--quiet
, il vous donnera simplement le code de sortie. 0 pour apparié, non 0 pour différé.MD5 est assez rapide, mais pas de façon éclatante. MD4 (
openssl md4
est le meilleur que vous obtenez sur la ligne de commande, je crois) est environ deux fois plus rapide (ni lui ni MD5 ne sont sécurisés, mais les deux sont à peu près aussi résistants aux collisions lorsque personne ne tente de les renverser). SHA-1 (sha1sum
) est plus sûr, mais plus lent; SHA-256 (sha256sum
) est sécurisé, mais encore plus lent. CRC32 devrait être beaucoup plus rapide, mais est plus court et aura donc plus de collisions aléatoires. C'est aussi totalement dangereux.la source
zdiff
semble un gaspillage car je veux juste savoir si un fichier a changé, pas quoi .zcmp
semble intéressant, je vais essayer ça.La réponse de @derobert est excellente, bien que je veuille partager d'autres informations que j'ai trouvées.
gzip -l -v
Les fichiers compressés avec gzip contiennent déjà un hachage (mais pas sécurisé, voir ce message SO ):
On peut combiner le CRC et la taille non compressée pour obtenir une empreinte digitale rapide:
cmp
Pour vérifier si deux octets sont égaux ou non, utilisez
cmp file1 file2
. Maintenant, un fichier compressé a un en-tête avec les données et le pied de page (CRC plus la taille d'origine) ajoutés. La description du format gzip montre que l'en-tête contient l'heure à laquelle le fichier a été compressé et que le nom du fichier est une chaîne terminée par zéro qui est ajoutée après l'en-tête de 10 octets.Ainsi, en supposant que le nom de fichier est constant et que la même commande (
gzip "$name"
) est utilisée, on peut vérifier si deux fichiers sont différents en utilisantcmp
et en sautant les premiers octets, y compris l'heure:Remarque : l'hypothèse selon laquelle les mêmes options de compression sont importantes, sinon la commande signalera toujours le fichier comme différent. Cela se produit car les options de compression sont stockées dans l'en-tête et peuvent affecter les données compressées.
cmp
regarde juste les octets bruts et ne l'interprète pas comme gzip.Si vous avez des noms de fichiers de la même longueur, vous pouvez essayer de calculer les octets à ignorer après avoir lu le nom du fichier. Lorsque les noms de fichiers sont de taille différente, vous pouvez exécuter
cmp
après avoir ignoré les octets, commecmp <(cut -b9- file1) <(cut -b10- file2)
.zcmp
C'est certainement la meilleure façon de procéder, il compresse d'abord les données et commence à comparer les octets avec
cmp
(vraiment, c'est ce qui est fait dans le shellscriptzcmp
(zdiff
)).Une note, n'ayez pas peur de la note suivante dans la page de manuel:
Lorsque vous avez un Bash suffisamment nouveau, la compression n'utilisera pas de fichier temporaire, juste un tube. Ou, comme le dit la
zdiff
source:la source
gzip -v -l
signalera l'heure du fichier au lieu de MTIME si les quatre octets MTIME dans l'en-tête sont nuls. Notez également que si MTIME est là, c'est généralement un peu avant l'heure du fichier car c'est lorsque la compression a commencé.Pour comparer deux fichiers gzip, juste le contenu, une commande, non
diff
, simplement comparermd5sum
Vous pouvez également "filtrer" les différences pertinentes,
En cas de script, je recommanderais une fonction de filtre (non testée, juste un exemple),
la source
cmp
.zcat
etgrep
peut être fusionné enzgrep
.zcat
c'est justegunzip -c
. Utilisez le bon outil pour le bon travail, KISS est meilleur que ballonnement. Dans ce cas, je passerais mon temps à écrire quelque chose qui génère des liens durs au besoin, c'est plus amusant.