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

12

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 en jachère:

.
├── 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 dossiers 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?

eDeviser
la source

Réponses:

17

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-coquilles, et l'effet des cdseules durées dans la sous-coquille, vous n'avez donc pas à cdrevenir au répertoire d'origine.

Si d1, d2etc. sont en fait des fichiers et des répertoires eux - mêmes pas, puis utilisez l' -joption de :

-j
--junk-chemins
Stocke juste le nom d'un fichier enregistré (junk le chemin), et ne stocke pas les noms de répertoire. Par défaut, zip stockera le chemin complet (par rapport au répertoire courant).

muru
la source
19

Vous pouvez utiliser findpour obtenir la liste des fichiers et exécuter zip -j myfilespour 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, cela ne fonctionne que pour les fichiers , les répertoires seront ignorés par zip -j. Pour que cela fonctionne aussi pour les répertoires, disons que nous voulons emballer d0, d1et le f3répertoire entier dans l'exemple ci-dessus, la findligne 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
dessert
la source
18

L'utilisation de l'option -j supprimera le chemin d'accès du fichier.

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

référence

délire
la source
si l'un des chemins d'accès que vous passez ne sont pas des fichiers mais des répertoires, ces répertoires ne seront pas ajoutés au zipfichier avec l' -joption.
Dan
@dan --si vous voulez tous les fichiers dans un répertoire sans le chemin alorszip -j myfiles directory/*
ravery