Fügen Sie eine Datei tief in einer Zip-Datei hinzu


7

Sagen wir , ich möchte die Datei hinzufügen file.txtzu foo.zip, ich konnte einfach tun zip -u foo.zip file.txt.

Innerhalb der Zip-Datei existiert jedoch bereits ein Ordner mit dem Pfad foo.zip/very/many/paths/(relativ zur Zip-Datei).

Wie würde ich file.txtder Zip-Datei hinzufügen , damit sie sich in der Zip-Datei befindet foo.zip/very/many/paths/file.txt?

Ich könnte zuerst die benötigte Verzeichnisstruktur erstellen, aber gibt es keinen einfacheren Weg?

Normalerweise würde ich das so machen:

$ ls
file.txt
foo.zip
$ mkdir sehr
$ mkdir sehr / viele
$ mkdir sehr / viele / Pfade
$ cp file.txt sehr / viele / Pfade
$ zip -u foo.zip sehr / viele / Pfade / file.txt
$ rm -rf sehr

8
Ich weiß nicht, ob dies einfacher möglich ist, aber Sie können zumindest mehrere mkdirBefehle kürzen , mit mkdir -p very/many/pathsdenen nach Bedarf übergeordnete Verzeichnisse erstellt werden. ;)
speakr

Wenn Sie es oft tun müssen, erstellen Sie einfach ein Bash-Skript, das es automatisiert. Nehmen Sie Argumente Ihr Archiv und den Pfad und die Datei im Archiv wieupdatezip very/many/path/file.txt file.txt
Depado

1
7z hat eine Option dafür, 7z a yourfile.7z -sivery/many/paths/file.txt < file.txtaber wenn ich dies mit zip versuche, führt dies leider zu einem Fehler. Also funktioniert diese Funktion nur mit 7z, nicht mit zip / tar :(
frostschutz

Mögliches Duplikat von Datei zu einem anderen Pfad hinzufügen (aber die Frage hat keine positive oder akzeptierte Antwort erhalten).
Lgeorget

Antworten:


2

Pythons Zipfile-Bibliothek verwenden?

~/wrk/tmp$ ls test.zip
ls: cannot access test.zip: No such file or directory

OK. Derzeit gibt es keine 'test.zip' ...

~/wrk/tmp$ python -c 'import zipfile,sys ; zipfile.ZipFile(sys.argv[1],"a").write(sys.a
rgv[2],sys.argv[3])' test.zip /etc/motd text/motd

Fügen wir '/ etc / motd' als 'text / motd' zur nicht existierenden Zip-Datei hinzu ...

~/wrk/tmp$ ls -l test.zip 
-rw-r--r-- 1 yeti yeti 473 Mar 23 09:51 test.zip

Die zipfile-Bibliothek war nett genug, um 'test.zip' zu erstellen.

~/wrk/tmp$ unzip -lv test.zip 
Archive:  test.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
     357  Stored      357   0% 2014-03-20 15:47 ff1b8b7f  text/motd
--------          -------  ---                            -------
     357              357   0%                            1 file

..und es scheint zu enthalten, was ich wollte ...

Lassen Sie es uns überprüfen, indem Sie es auf stdout entpacken ...

~/wrk/tmp$ unzip -p test.zip text/motd
Linux aurora 3.2.0-0.bpo.4-amd64 #1 SMP Debian 3.2.54-2~bpo60+1 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

Fein!

Jetzt fügen wir eine 2. Datei hinzu ...

~/wrk/tmp$ python -c 'import zipfile,sys ; zipfile.ZipFile(sys.argv[1],"a").write(sys.argv[2],sys.argv[3])' test.zip /etc/issue otherdir/issue
~/wrk/tmp$ ls -l test.zip 
-rw-r--r-- 1 yeti yeti 605 Mar 23 09:52 test.zip
(yeti@aurora:1)~/wrk/tmp$ unzip -lv test.zip 
Archive:  test.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
     357  Stored      357   0% 2014-03-20 15:47 ff1b8b7f  text/motd
      28  Stored       28   0% 2012-09-21 22:52 f9c3990c  otherdir/issue
--------          -------  ---                            -------
     385              385   0%                            2 files
~/wrk/tmp$ unzip -p test.zip otherdir/issue                                            Debian GNU/Linux 6.0 \n \l

~/wrk/tmp$ _

0

Eine Möglichkeit, die ich vorschlagen würde, ist das Entpacken, Verschieben der Datei und anschließendes erneutes Komprimieren.

Nehmen wir als Beispiel an, wir haben diese Zip-Datei:

Archive:  foo.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2013-01-30 14:38   very/
        0  2013-01-30 14:38   very/many/
        0  2013-01-30 14:38   very/many/paths/
        0  2013-01-30 14:38   very/many/paths/foo.txt
        0  2013-01-30 14:38   file.txt
---------                     -------
        0                     5 files

Um die Datei zu entpacken, erstellen wir zunächst ein Verzeichnis /tmp. Dann werden wir die folgenden Aktionen ausführen:

  1. Entpacken Sie foo.zipin unser temporäres Verzeichnis
    d=$(mktemp -t -d foo.zip.XXXXXX) && unzip -d $d foo.zip
  2. Verschieben Sie die Datei in ihren neuen Pfad (relativ zum temporären Verzeichnis $d).
    mv ${d}/file.txt ${d}/very/many/paths/
  3. In der Subshell: cdum temp tem & Rekomprimieren Sie alles in eine neue Zip-Datei
    ( cd $d && zip -r foo.zip ./* )
  4. Verschieben Sie die neue Zip-Datei aus dem temporären Verzeichnis, um die alte zu ersetzen
    mv ${d}/foo.zip ./
  5. Aufräumen :-)
    rm -rf ${d}

Richtig, aber ineffizient, zip ist kein solides Komprimierungsformat und ermöglicht das Hinzufügen und Entfernen von Inhalten ohne erneute Komprimierung. Wenn jedoch häufig Dateien und sogar die gesamte Verzeichnisstruktur zu einer Zip-Datei hinzugefügt werden, kann etwas anders ausgeführt werden.
Orion

Es ist bekannt, dass das ZIP-Format bei weitem nicht das höchste Komprimierungsverhältnis aufweist. Es gibt heutzutage viel bessere Möglichkeiten wie 7z. Das ZIP-Format ist jedoch wahrscheinlich das portabelste Format, da in bestimmten Betriebssystemen Unterstützung integriert ist ;-). Außerdem hat das OP in der Frage speziell nach einem Beispiel für das ZIP-Format gefragt.
TrinitronX

-1

Sie können Ant dafür verwenden.

Erstellen Sie eine Datei mit dem Namen build.xml:

<project name="zip-utils">

    <target name="add-file-to-zip">
        <fail message="Property 'zip' must be set" unless="zip" />
        <fail message="Property 'file' must be set" unless="file" />
        <fail message="Property 'path' must be set" unless="path" />

        <available file="${zip}" property="zip.exists" />
        <fail message="Zip file missing: ${zip}" unless="zip.exists" />

        <available file="${file}" property="file.exists" />
        <fail message="File missing: ${file}" unless="file.exists" />

        <dirname property="file.dir" file="${file}"/>
        <basename property="file.filename" file="${file}"/>

        <zip destfile="${zip}" update="true">
            <zipfileset fullpath="${path}" dir="${file.dir}" includes="${file.filename}"/>
        </zip>
    </target>

</project>

Dann können Sie es im gleichen Verzeichnis build.xmlwie folgt ausführen:

ant add-file-to-zip -Dzip=foo.zip -Dfile=file.txt -Dpath=/very/many/paths/file.txt

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.