Jak utworzyć zip z wieloma plikami bez podfolderów?

12

Sytuacja początkowa:

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

Co muszę zrobić:

Chciałbym utworzyć zip zawierający d0, d1 i d4, który musi mieć następującą strukturę:

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

Co już próbowałem:

Próbowałem z tym zip myfiles d0 f1/d1 f2/f3/d4. Ale zachowuje to oryginalną strukturę folderów, co nie jest tym, czego chcę.

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

Pytanie Jak utworzyć zip z wieloma plikami bez podfolderów?

eDeviser
źródło

Odpowiedzi:

17

Ręcznie możesz utworzyć plik zip i zaktualizować go:

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

Nawiasy tworzą podpowłoki, a efekt cdjedynych trwa w podpowłoce, więc nie musisz cdwracać do oryginalnego katalogu.

Jeśli d1, d2itp są rzeczywiście plików i katalogów nie same, a następnie użyj -jopcji:

-j
--junk-paths
Przechowuj tylko nazwę zapisanego pliku (śmieci ścieżkę) i nie przechowuj nazw katalogów. Domyślnie zip zapisze pełną ścieżkę (względem bieżącego katalogu).

muru
źródło
19

Możesz użyć, findaby uzyskać listę plików i wykonać, zip -j myfilesaby spakować je, ignorując ścieżki:

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

Przykład

$ 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

Jednak działa to tylko dla plików , katalogi zostaną zignorowane przez zip -j. Aby to działało również dla katalogów, powiedzmy, że chcemy spakować d0, d1a cały f3katalog w powyższym przykładzie, findlinia staje się nieco bardziej skomplikowana:

$ 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
deser
źródło
18

Użycie opcji -j spowoduje usunięcie ścieżki z pliku.

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

odniesienie

pustkowie
źródło
jeśli którakolwiek z przekazywanych ścieżek nie jest zipplikiem, ale katalogiem, katalogi te nie zostaną dodane do pliku z -jopcją.
Dan
@dan - jeśli chcesz wszystkie pliki w katalogu bez ścieżki, wtedyzip -j myfiles directory/*
ravery