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
Tyilo
quelle
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$ _
Rui F Ribeiro
quelle
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}
TrinitronX
quelle
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

tbrugz
quelle