web-dev-qa-db-fra.com

Comment créer un Zip avec plusieurs fichiers sans sous-dossiers?

Situation initiale:

.
├── d0
├── f0
├── f1
│   └── d1
└── f2
    └── f3
        ├── d2
        ├── d3
        └── d4

Ce que je dois faire:

Je voudrais créer un Zip contenant d0, d1 et d4 qui doit avoir la structure suivante:

.
├── d0
├── d1
└── d4

Ce que j'ai déjà essayé:

Je l'ai essayé avec Zip myfiles d0 f1/d1 f2/f3/d4. Mais cela conserve la structure de dossier d'origine, ce qui n'est pas ce que je veux.

.
├── d0
├── f1
│   └── d1
└── f2
    └── f3
        └── d4

Question Comment créer un zip avec plusieurs fichiers sans les sous-dossiers?

11
eDeviser

Manuellement, vous pouvez créer le fichier Zip et le mettre à jour:

Zip myfiles d0
(cd f1; Zip -u ../myfiles.Zip d1)
(cd f2/f3; Zip -u ../../myfiles.Zip d4)

Les parenthèses créent des sous-coques, et l'effet de cd ne dure que dans la sous-coque, vous n'avez donc pas besoin de cd pour revenir au répertoire d'origine.

Si d1, d2, etc. sont en fait des fichiers et non des répertoires eux-mêmes, utilisez l'option -j:

- j
- chemins de courrier indésirable
Stockez uniquement le nom d'un fichier enregistré (chemin du fichier indésirable) et ne stockez pas les noms de répertoire. Par défaut, Zip stockera le chemin complet (par rapport au répertoire actuel).

17
muru

Vous pouvez utiliser find pour obtenir la liste de fichiers et exécuter Zip -j myfiles pour les emballer en ignorant les chemins:

find . -name "d[014]" -exec Zip -j myfiles {} +

Exemple

$ tree
.
├── d0
├── f0
├── f1
│   └── d1
└── f2
    └── f3
        ├── d2
        ├── d3
        └── d4

$ find . -name "d[014]" -exec Zip -j myfiles {} +
  adding: d1 (stored 0%)
  adding: d4 (stored 0%)
  adding: d0 (stored 0%)

$ unzip -l myfiles.Zip
Archive:  myfiles.Zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2017-10-09 10:47   d1
        0  2017-10-09 10:48   d4
        0  2017-10-09 10:47   d0
---------                     -------
        0                     3 files

Cependant ceci ne fonctionne que pour les fichiers, les répertoires seront ignorés par Zip -j. Pour que cela fonctionne également avec les répertoires, supposons que nous voulions compresser d0, d1 et le répertoire entier f3 dans l'exemple ci-dessus, la ligne find devient un peu plus compliquée:

$ find . \( -name "d[01]" -o -name "f3" \) -exec sh -c 'p=$(pwd); for i in $0 $@; do cd ${i%/*}; Zip -ur "$p"/myfiles ${i##*/}; cd "$p"; done' {} +
        Zip warning: /home/dessert/myfiles.Zip not found or empty
  adding: d1 (stored 0%)
  adding: f3/ (stored 0%)
  adding: f3/d3 (stored 0%)
  adding: f3/d2 (stored 0%)
  adding: f3/d4 (stored 0%)
  adding: d0 (stored 0%)
$ unzip -l myfiles.Zip 
Archive:  myfiles.Zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2017-10-11 10:18   d1
        0  2017-10-11 10:19   f3/
        0  2017-10-11 10:19   f3/d3
        0  2017-10-11 10:19   f3/d2
        0  2017-10-11 10:19   f3/d4
        0  2017-10-11 10:17   d0
---------                     -------
        0                     6 files
19
dessert

L'utilisation de l'option -j supprimera le chemin du fichier.

Zip -j myfiles d0 f1/d1 f2/f3/d4 

référence

18
ravery