Как создать ZIP с несколькими файлами без подпапок?

12

Первоначальный ситуация:

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

Что мне нужно сделать:

Я хотел бы создать почтовый индекс, содержащий d0, d1 и d4, который должен иметь следующую структуру:

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

Что я уже пробовал:

Я попробовал это с zip myfiles d0 f1/d1 f2/f3/d4. Но это сохраняет первоначальную структуру папок, а это не то, что я хочу.

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

Вопрос Как создать ZIP с несколькими файлами без подпапок?

eDeviser
источник

Ответы:

17

Вручную вы можете создать zip-файл и обновить его:

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

Скобки создают подоболочки, и эффект cdединственного сохраняется в подоболочке, поэтому вам не нужно cdвозвращаться в исходный каталог.

Если d1, d2и т.д., на самом деле файлы и сами не каталоги, а затем использовать -jопцию:

-j
--junk-paths
Хранить только имя сохраненного файла (мусорный путь) и не хранить имена каталогов. По умолчанию zip будет хранить полный путь (относительно текущего каталога).

Мур
источник
19

Вы можете использовать, findчтобы получить список файлов и выполнить zip -j myfilesих упаковку, игнорируя пути:

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

пример

$ 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

Однако это работает только для файлов , каталоги будут игнорироваться zip -j. Чтобы заставить это работать и для каталогов, скажем, мы хотим упаковать d0, d1и весь f3каталог в приведенном выше примере, findстрока становится немного более сложной:

$ 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
Десерт
источник
18

Использование опции -j удалит путь из файла.

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

ссылка

ravery
источник
если какой-либо путь, который вы передаете, не является файлом, а является каталогом, эти каталоги не будут добавлены в zipфайл с -jпараметром.
Дан
@dan - если вы хотите, чтобы все файлы в каталоге без пути, тогдаzip -j myfiles directory/*
ravery