使用Python的zipfile库?

使用Python的zipfile库?

假设我想将文件添加file.txtfoo.zip,我可以这样做zip -u foo.zip file.txt

但是,在 zip 文件内已经存在一个带有路径的文件夹foo.zip/very/many/paths/(相对于 zip 文件)。

我将如何添加file.txt到 zip 文件,以便它在 zip 文件内的位置是foo.zip/very/many/paths/file.txt

我可以先创建所需的目录结构,但是没有更简单的方法吗?

我通常会这样做:

$ls
文件.txt
foo.zip
$ mkdir 非常
$ mkdir 非常/很多
$ mkdir 非常/许多/路径
$ cp file.txt 非常/许多/路径
$ zip -u foo.zip 非常/许多/路径/file.txt
$ rm -rf 非常

答案1

使用Python的zipfile库?

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

好的。现在没有“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

让我们将“/etc/motd”作为“text/motd”添加到不存在的zip文件中...

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

zipfile 库足够好,可以创建“test.zip”。

~/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

..它似乎包含了我想要的东西......

让我们通过将其解压缩到标准输出来检查它......

~/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.

美好的!

现在我们添加第二个文件...

~/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$ _

答案2

我建议的一种方法是解压缩、移动文件,然后重新压缩。

举个例子,假设我们有这个 zip 文件:

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

要解压文件,我们/tmp首先创建一个目录。然后我们将执行以下操作:

  1. 解压foo.zip到我们的临时目录
    d=$(mktemp -t -d foo.zip.XXXXXX) && unzip -d $d foo.zip
  2. 将文件移动到新路径(相对于 temp dir $d
    mv ${d}/file.txt ${d}/very/many/paths/
  3. 在子 shell 中:cd到临时目录并将所有内容重新压缩到新的 zip 文件中
    ( cd $d && zip -r foo.zip ./* )
  4. 从临时目录中移动新的 zip 文件以替换旧的
    mv ${d}/foo.zip ./
  5. 清理 :-)
    rm -rf ${d}

答案3

您可以使用蚂蚁为了那个原因。

创建一个名为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>

然后,在 的同一目录中build.xml,您可以使用以下命令运行它:

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

相关内容