Wie erstelle ich eine Zip-Datei mit mehreren Dateien ohne Unterordner?

12

Ausgangssituation:

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

Was ich tun muss:

Ich möchte einen Reißverschluss erstellen, der d0, d1 und d4 enthält und die folgende Struktur haben muss:

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

Was ich schon versucht habe:

Ich habe es mit versucht zip myfiles d0 f1/d1 f2/f3/d4. Dadurch bleibt jedoch die ursprüngliche Ordnerstruktur erhalten, was ich nicht möchte.

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

Frage Wie erstelle ich eine Zip-Datei mit mehreren Dateien ohne Unterordner?

eDeviser
quelle

Antworten:

17

Manuell können Sie die Zip-Datei erstellen und aktualisieren:

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

Die Klammern erstellen Unterschalen, und die Wirkung der cdeinzigen Schalen bleibt in der Unterschale erhalten, sodass Sie nicht cdzum ursprünglichen Verzeichnis zurückkehren müssen.

Wenn d1, d2etc. tatsächlich Dateien und Verzeichnisse nicht selbst, dann die Verwendung -jOption:

-j
--junk-path
Speichert nur den Namen einer gespeicherten Datei (Junk-Pfad) und keine Verzeichnisnamen. Standardmäßig speichert zip den vollständigen Pfad (relativ zum aktuellen Verzeichnis).

muru
quelle
19

Sie können verwenden find, um die Dateiliste abzurufen und auszuführen zip -j myfiles, um sie zu packen, wobei Sie die Pfade ignorieren:

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

Beispiel

$ 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

Dies funktioniert jedoch nur für Dateien . Verzeichnisse werden von ignoriert zip -j. Damit dies auch für Verzeichnisse funktioniert, sagen wir, wir möchten packen d0, d1und das gesamte f3Verzeichnis im obigen Beispiel wird die findZeile etwas komplizierter:

$ 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
quelle
18

Mit der Option -j wird der Pfad aus der Datei entfernt.

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

Referenz

Ravery
quelle
Wenn einer der Pfade, die Sie übergeben, keine Dateien, sondern Verzeichnisse sind, werden diese Verzeichnisse zipmit der -jOption nicht zur Datei hinzugefügt .
Dan
@dan - wenn Sie alle Dateien in einem Verzeichnis ohne den Pfad dann wollenzip -j myfiles directory/*
ravery