Grimoire-
Command
.es

GNU+Linux command memo

Memo_8 : Archives, compression et décompression de fichiers

D’après l’édition 11 des travaux d’Alain Leaper, 2018-04-10
Licence GPL

1. Introduction

Il est possible de réduire la taille (en octets) de la plupart des fichiers informatiques, sans rien perdre de leur contenu. Cette opération est connue sous le nom de compression de fichier. Une forme simple de compression de fichier consiste à chercher des portions de fichier identiques, à noter leur emplacement, et à ne garder qu’une des occurrences de cette portion de fichier. C’est le principe de la factorisation en mathématique.

Le fichier ainsi obtenu occupe moins de place sur le disque dur, et est plus rapide à recopier sur le réseau.

La compression de fichiers est souvent liée à un autre principe simple, la création d’archives. Une archive est ici un fichier regroupant le contenu de plusieurs autres fichiers. La forme basique consiste à coller le contenu de plusieurs fichiers à la suite dans un seul nouveau fichier cible. On obtient alors un nouveau gros fichier, plus rapide à recopier (à graver, à déplacer) qu’une série de petits fichiers, car le temps passé à faire les vérifications (notamment celle de place disponible sur le support cible d’une copie) n’est perdu qu’une fois pour l’archive, alors qu’il l’aurait été pour chaque petit fichier sinon. On factorise ici ce qui se passe avant et après la copie d’un fichier, pour ne garder que le temps de la copie elle-même.

Toutefois, si on ne copie que le contenu des fichiers à la suite les uns des autres, on perd les noms de ces fichiers, ainsi que leurs permissions… et il faut bien noter leur taille quelque part pour pouvoir les séparer ensuite. On utilise donc des logiciels spécialisés pour faire ça proprement.

Une fois notre archive créée, puisqu’on a réalisé une tâche répétitive, on a probablement créé des répétitions dans le contenu de notre fichier archive. Et puis ce dernier pourrait contenir plusieurs copies de fichiers très ressemblant (comme plusieurs version d’une lettre ou d’un code source). On associe donc généralement l’agglutination de fichiers en archive, avec la compression de fichier.

On obtient alors des archives comprimées, doublement pratiques et rapides à copier.

Dans ce mémo, nous allons voir les commandes permettant de gérer les principaux formats de compression de fichier, puis nous verrons le couteau suisse du domaine chez GNU+Linux : tar.

2. Outils de compression / décompression de fichiers : GZip, BZip2 et XZ

Le format gzip est un format historique du monde Unix. Il est encore largement utilisé aujourd’hui (notamment pour ce qui est du transfert des pages web, qui vous arrivent le plus souvent compressées), car il est extrêmement rapide en ce qui concerne le temps de compression et de décompression.

Le format bzip2 est lui une évolution cherchant à obtenir des fichiers plus petits en consacrant plus de temps aux astuces mises en place pour obtenir un fichier plus petit.

De nombreuses autres alternatives ont été développées, et elles sont minutieusement comparées entre elles en fonction de critères comme : le temps de compression, celui de décompression, la quantité de mémoire RAM utilisée pour ces opérations, ou encore l’efficacité de la compression.

Le format xz est actuellement le plus complémentaire du gzip. En effet le xz a été conçu pour être "le plus efficace possible" dans la compression obtenue, et le plus rapide possible dans la décompression (en utilisant peu de mémoire RAM). Il est donc logiquement lent et gourmand en RAM à la compression. Ces choix ont été fait en tenant compte du fait qu’on peut être amené à décompresser plusieurs fois une archives après sa création (il semble donc plus intéressant d’optimiser le temps de décompression). Techniquement, xz est une implémentation de l’algorithme de compression LZMA (introduit par le format de fichier .7z et d’une amélioration de ce format nommée LZMA2 (tous deux à base de chaînes de Markov cachées). L’utilitaire xz, contrairement à 7z est conçu pour remplacer facilement gzip ou bzip2 en supportant la même syntaxe et les mêmes options.

Enfin, évoquons rapidement le cas des algorithmes de compression spécifiques pour un type de fichiers donné :

  • compression de la musique, en FLAC (proche d’un Wav "GZippé") ou avec pertes d’une partie jugée négligeable des données en MP3 (qui supprime la partie normalement inaudible des sons car trop grave ou aiguë) ;

  • compression des images en PNG (proche d’un Bitmap "GZippé"), ou avec perte de qualité en GIF ou JPEG qui conservent moins de couleurs donnant un résultat plus terne ou des dégradés en escalier ;

  • compression des vidéos : GIF animé, MPEG, MP4, H.264, H.265 (tout est avec perte de qualité dans la compression, une seconde de vidéo représentant généralement 25 images, la question de l’efficacité de la compression est apparue très vite dans ce domaine…) ;

  • ou encore les fichiers de bureautique, nativement compressés en GZip par leur éditeur, notamment LibreOffice.

La commande pour comprimer un fichier est de la forme :

$ cmd -options nomDeFichier
$ gzip monFichier (1)
$ bzip2 monFichier (2)
$ xz monFichier (3)
1 monFichier est remplacé par monFichier.gz
2 monFichier est remplacé par monFichier.bz2
3 monFichier est remplacé par monFichier.xz

L’option -9 de gzip permet d’indiquer qu’on souhaite passer plus de temps à tenter de comprimer d’avantage le fichier. La compression qui est résulte est généralement un peu plus importante. La commande xz comprime de son mieux dès le début et vous aurez le temps de vous en souvenir, vu qu’elle consomme également beaucoup de ressources système ce faisant.

$ gzip -9 monFichier (1)
1 donne une taille plus faible pour monFichier.gz, mais prends un peu plus de temps.

Remarque : contrairement aux bruits qui courent, la compression avec bzip2 n’est pas toujours meilleure que celle obtenue par gzip, il faut essayer. Il peut également arriver qu’XZ ne soit pas vraiment meilleur que gzip. C’est notamment le cas des fichiers présentant de grosses similitudes faciles à trouver. Mais ce n’est pas toujours évident à anticiper.

L’option -c (de gzip ou bzip2) permet d’utiliser le canal de sortie standard, et donc de le rediriger :

$ gzip -c monFichier > autreFichier.gz (1)
1 monFichier est conservé

L’option -d (gzip ou bzip2) permet de décompresser un fichier compressé précédemment par le même utilitaire.

$ bzip2 -d monFichier.bz2

Remarque :

gzip -d monFichier.gz peut être remplacé par : gunzip monFichier.gz

bzip2 -d monFichier.bz2 peut être remplacé par : bunzip2 monFichier.bz2

xz -d monFichier.xz peut être remplacé par : unxz monFichier.bz2

3. tar : gestion d’archives

Le nom vient des archives sauvegardées sur bandes magnétiques : tape archives.

3.1. Forme générale (-c)

$ tar -cvf nomArchive.tar fichier_0 fichier_1 fichier_2 …
  • fichier_0 fichier_1… sont les fichiers à mettre dans l’archive nomArchive.tar

  • * est utilisable : exemple tar -cf nomArchive.tar ./fich*

  • les répertoires et leurs sous-répertoires sont archivés jusqu’à atteindre les fichiers.

  • la structure de l’archive dépend de la manière dont le répertoire de "départ" est spécifié : si le chemin complet est indiqué, celui-ci sera retrouvé à l’extraction.

  • -c (creation) demande la création d’un fichier d’archive.

  • -f (file) : désigne le nom du fichier archive, cette option est quasiment obligatoire !

Bien que cela ne soit pas obligatoire, et puisque ce n’est pas automatique, notons qu’il est préférable de spécifier une extension .tar pour le nom des fichiers d’archive.
  • -v (verbose) : mode "verbeux", affiche, en cours d’opération, la liste des fichiers traités. -vv donnerait encore plus d’infos…

3.2. Extraire les fichiers / répertoires composant une archive : option -x

$ tar -xvf nomArchive.tar (1)
$ tar -xvf nomArchive.tar nomComposant (2)
1 extraction de la totalité des composants
2 extraction d’un composant particulier : fichier ou répertoire
nomComposant doit être le nom complet (c-à-d avec le chemin) tel qu’il apparaît dans l’archive : tar -tvf nomArchive.tar pour connaître ce nom.

3.3. Ajout d’un (ou plusieurs) fichier(s) à une archive existante : option -r

$ tar -rvf nomArchive.tar nouveauFichier (1)
1 ajoute nouveauFichier dans nomArchive.tar
Cette opération n’est pas possible sur une archive compressée.

3.4. Voir le contenu d’une archive : option -t

$ tar -tvf nomArchive.tar

Il est important de prendre connaissance de la structure d’une l’archive avant de décider dans quel répertoire doit se dérouler l’extraction.

3.5. Stratégie pour la création / extraction d’archives afin de garder la même arborescence

  • Si le chemin absolu (c-à-d à partir de la racine /) a été spécifié lors de la création, alors pour l’extraction, se mettre sous la racine (/).

  • Si un chemin relatif, à partir du répertoire courant a été spécifié lors de la création tar -cvf nomArchive.tar ./* Alors pour l’extraction, créer si nécessaire, et se placer dans le répertoire désiré.

  • Si un chemin relatif à partir du répertoire parent (de celui à archiver) a été spécifié lors de la création tar -cvf nomArchive.tar ./repertoireFils Alors pour l’extraction se placer dans ce répertoire parent.

Exemple : archiver le répertoire de travail de l’utilisateur pierre (/home/pierre)

$ cd /home
$ tar -cvf pierreArchi.tar ./pierre
$ cd /home (1)
$ tar -xvf pierreArchi.tar
1 À l’extraction (par exemple sur une autre station)

Il existe l’option -C pour changer le répertoire destination.

$ tar -C repDesti -xcf /chemin/nomArchive.tar

Va extraire l’archive dans repDesti (au lieu du répertoire courant). Cette option est très pratique, en particulier lorsque l’on doit repartir de la racine (ou d’un niveau "élevé" dont on n’est pas propriétaire) pour extraire dans un niveau dont on possède les droits d’accès en écriture.

  • tar n’est pas "ré-entrant" : il n’y a pas de problème pour créer une archive à partir du répertoire courant en sélectionnant tous les fichiers :

$ tar -cvf nomArchive.tar ./* (1)
1 ne créer pas boucle, pas d’auto archivage récursif de nomArchive.tar

Il est possible de créer l’archive dans un répertoire autre que dans le répertoire courant :

$ tar -cvf ~/mesAchives/ceRepertoire.tar ./*

3.6. Création / extraction d’archives compressées

Plutôt que de compresser les fichiers puis de les archiver, ou d’archiver puis de compresser l’archive, il est plus commode de procéder en une seule opération :

  • -z compression / décompression par gzip

tar -zcvf nomArchive.tar.gz *
tar -zxvf nomArchive.tar.gz
  • -j compression / décompression par bzip2

tar -jcvf nomArchive.tar.bz2 *
tar -jxvf nomArchive.tar.bz2
  • -J compression / décompression par xz

tar -Jcvf nomArchive.tar.xz *
tar -Jxvf nomArchive.tar.xz

Remarques :

  • bien que l’extension .tar.gz ne soit pas obligatoire, elle est recommandée, en cas de doute la commande file nomArchive indique la nature du fichier

  • l’ordre des options n’est pas fixe, excepté pour l’option -f qui doit être suivie du nom du fichier ciblé. De plus -v est facultatif, l’enlever rend juste la commande moins bavarde. Ainsi on peut décompresser une archive avec : tar -xJf nomArchive.tar.xz

  • pour voir la composition de l’archive l’option -z (ou -j, ou -J) n’est pas indispensable tar -tvf nomArchive.tar.bz2 idem tar -jtvf nomArchive.tar.bz2

  • il n’est pas possible de faire un ajout dans une archive compressée, impossible : tar -r

  • le canal d’entrée standard de tar peut être impliqué par le signe -. Certains auteurs utilisent cette possibilité, comme ci-dessous : $ zcat nomArchive.tar.gz | tar xvf -

  • On trouve aussi l’extension .tgz au lieu de .tar.gz

  • On trouve aussi l’extension .txz au lieu de .tar.xz

  • Il est possible, même sur une archive compressée, d’en extraire une partie : $ tar -Jxvf nomArchive.txz chemin/fichier

4. Autres utilitaires de création / extraction d’archives compressées

4.1. zip et unzip

$ zip -r nomArchive * (1)
$ unzip nomArchive.zip (2)
1 option -r archive aussi les sous répertoires (récursif). Crée une archive nomArchive.zip, à partir du répertoire courant.
2 extraction d’une archivve nomArchive.zip dans le répertoire courant.

4.2. 7z avec p7zip

$ p7zip -d nomArchive.7z (1)
1 option -d pour extraction

4.3. unrar-free et unrar

Il existe les commandes unrar-free et unrar dans Debian pour l’extraction des archives au format propriétaire .rar.

5. Recompression de fichiers à format spécifiques (PNG, FLAC, JPEG)

Les commandes jpegoptim et zopflipng permettent de recompresser des images JPEG / PNG sans perte de qualité :

$ find . -name \*.jpeg -exec jpegoptim -pt (1)

$ find . -regextype posix-extended -iregex '.*(jpeg|jpg)' -print0 | xargs -0 -P $((`nproc` / 2)) jpegoptim -pt (2)

$ find . -name \*.png -print0 | xargs -0 -P $((`nproc` / 2)) -I {} zopflipng -m --lossy_8bit --lossy_transparent -y {} {} (3)
1 JPG monotask
2 JPE?G multitask ; See Grep text in selected files for --print0 / -0 options.
3 PNG multitask

La commande reflac permet de recompresser des musiques FLAC au niveau maximum en gardant les métadonnées originales au format ID3 :

$ reflac --best $album_folder/ (1)
1 reflac from chungy/reflac Github repository.

La command sox permet elle de ré-échantillonner un fichier audio pour se débarrasser du superflux à l’écoute (au dela du 16 bits 44100 Hz). Cas pratique pour un album entier (la commande sox est en fin de 2e ligne…) :

$ cd the_album/
$ find . -name "*.flac" -print0 | xargs -0 -P 4 -I {} sox -S {} -r 48000 -b 16 "{}.sox.flac"
$ rename -f 's/\.sox\.flac//' *.flac