web-dev-qa-db-fra.com

Comment compresser plusieurs fichiers en ligne de commande?

Pardonnez cette question fondamentale, mais je n’ai pas pu trouver de réponse directe ni d’exemple simple sur l’échange de piles.

Disons que j'ai un dossier de fichiers que je voudrais compresser dans un fichier Zip que je peux partager avec mes terribles amis Windows (sinon, je n'utiliserais que tar et j'en aurais fini). Cela ressemble à ceci:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
└── test.jpg

En supposant que j'ai Zip installé:

Sudo apt-get install Zip

Je vois dans man Zip que cela me permet d’utiliser une liste de fichiers:

- @ listes de fichiers. Si une liste de fichiers est spécifiée sous la forme - @ [Pas sous MacOS], Zip extrait la liste des fichiers d'entrée de l'entrée standard au lieu de la ligne de commande. Par exemple,

          Zip -@ foo

J'ai donc créé Zip.lst qui ressemble à ceci:

cat Zip.lst

file1.txt
file2.txt
file3.txt
file.jpg
test.jpg

Et maintenant j'ai essayé:

Zip -@ Zip.lst

Mais il n'a rien fait sauf créer une ligne vide sur la console. Et je peux continuer à pousser Enter et il continue à faire plus de lignes vides sans apparemment exécuter la commande. Après quelques recherches, je me suis rendu compte que je devais mettre fin à la saisie en appuyant sur Ctrl+D

Mais maintenant je reçois cette erreur:

    Zip warning: missing end signature--probably not a Zip file (did you
    Zip warning: remember to use binary mode when you transferred it?)
    Zip warning: (if you are trying to read a damaged archive try -F)

Zip error: Zip file structure invalid (Zip.lst)

Quoi!? Comment ma liste simple n'est-elle pas une "structure de fichier valide"? Retour au manuel pour plus d'informations, et je regarde de plus près:

Si une liste de fichiers est spécifiée sous la forme - @ ...

Je l’essaye donc sans -@, et qu’au moins le traite tout de suite, sans avoir à appuyer sur Ctrl+D mais je reste avec la même erreur .

Heureusement, j'ai trouvé n commentaire sur une réponse à une question presque sans rapport qui m'a amené à réaliser que je devais nommer explicitement le fichier Zip. Cette erreur est due au fait qu’il essayait par défaut de créer un fichier Zip appelé Zip.lst. Mais puisque c’est le nom de ma liste, on pourrait penser qu’elle l’écraserait tout simplement, mais non, c’était en fait une tentative de mise à jour. Et comme la liste n’est évidemment pas un fichier Zip, nous obtenons l’erreur de structure de fichier non valide et il est maintenant clair pourquoi il est dit "probablement pas un fichier Zip". Alors j'ai essayé:

Zip files.Zip zip.lst

adding: Zip.lst (deflated 35%)

Eureka! Je vois que le fichier Zip a été créé et que mon dossier contient maintenant ceci:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
├── files.Zip
├── test.jpg
└── Zip.lst

Mais attendez avant de célébrer, confirmons d’abord le contenu du fichier Zip:

unzip -l files.Zip

Archive:  files.Zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       48  2016-05-24 15:30   Zip.lst
---------                     -------
       48                     1 file

Non! Eh bien, en fait, cela a du sens avec l'utilisation standard parce qu'il vient de compresser le fichier de liste que je lui ai donné. Finalement, j'ai réessayé avec -@ mais j'ai obtenu le même résultat.

Qu'est-ce que je fais mal?

En passant, je sais que je peux utiliser l'interface graphique et le faire à l'aide de la souris, mais je dois aussi écrire un script pour l'écrire. En général, je suis plus rapide dans la CLI lorsque je sais ce que je fais.

13
Jeff Puckett

Utiliser la redirection du fichier <

Zip files.Zip -@ < Zip.lst

Ou vous pouvez sauter la liste et simplement

Zip files.Zip *.txt *.jpg

merci steeldriver

Réponse historique

Je suis heureux je peux répondre à ma propre question parce que je voulais faire la chronique de mon émoi dans l'espoir que les autres personnes qui suivraient dans mon chemin de larmes pourraient être épargnées en cherchant des mots clés.

Finalement, j'ai découvert la bonne réponse , mais elle a été envoyée à la mauvaise question .

Quelques points de clarté:

  • Le manuel ne fait pas référence à une liste littérale comme dans un fichier, mais plutôt à la liste des fichiers sur la console.
  • Il est compréhensible que quelqu'un puisse être induit en erreur en pensant que foo faisait référence à la liste de fichiers, mais il est en fait destiné à représenter le nom du fichier Zip en sortie.
  • La liste des fichiers est omise dans l'exemple car elle utilise le commutateur -@, ce qui montre qu'il "prend la liste des fichiers d'entrée de entrée standard au lieu de ligne de commande "

Comprenant cela, nous sommes maintenant armés de diverses manières pour atteindre notre objectif.

Premièrement, en utilisant la liste de fichiers que nous avons créée, nous pouvons lire la liste avec cat et rediriger la sortie avec un tuyau comme entrée standard vers Zip:

cat Zip.lst | Zip -@ files.Zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Voir que adding: ... pour chaque fichier est certainement un bon signe, mais nous avions espéré avant, alors confirmons simplement:

unzip -l files.Zip

Archive:  files.Zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2016-05-24 14:54   file1.txt
        0  2016-05-24 14:54   file2.txt
        0  2016-05-24 14:54   file3.txt
        0  2016-05-24 15:00   file.jpg
        0  2016-05-24 14:59   test.jpg
---------                     -------
        0                     5 files

SWEET! Mais qui veut quand même créer une liste à utilisation unique? C'est une façon détournée de résoudre ce scénario particulier. Il serait préférable d’obtenir une liste de ls et de la diriger vers Zip:

ls | Zip -@ files.Zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Fabuleux! Créons maintenant des filtres avec l’impressionnant pouvoir de grep pour simplement décompresser le jpg, par exemple:

ls | grep .jpg | Zip -@ images.Zip

  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Ou simplement des fichiers commençant par "file"

ls | grep file. | Zip -@ files.Zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
18
Jeff Puckett

la commande la plus simple avec un niveau de compression maximal

Zip -9 -r filename.Zip /path/to/dir singlefile.jpg 
5
Ansyori