Thêm tệp vào sâu bên trong tệp zip


7

Nói rằng tôi muốn thêm tập tin file.txtvào foo.zip, tôi chỉ có thể làm zip -u foo.zip file.txt.

Tuy nhiên, bên trong tệp zip đã tồn tại một thư mục có đường dẫn foo.zip/very/many/paths/(tương đối với tệp zip).

Làm cách nào file.txtđể thêm tệp zip vào vị trí bên trong tệp zip foo.zip/very/many/paths/file.txt?

Tôi có thể tạo cấu trúc thư mục cần thiết trước tiên, nhưng không phải là cách dễ dàng hơn sao?

Tôi thường làm như thế này:

$ ls
file.txt
foo.zip
$ mkdir rất
$ mkdir rất / nhiều
$ mkdir rất / nhiều / đường dẫn
$ cp file.txt rất / nhiều / đường dẫn
$ zip -u foo.zip rất / many / path / file.txt
$ rm -rf rất

8
Tôi không biết nếu điều này có thể được thực hiện dễ dàng hơn nhưng ít nhất bạn có thể rút ngắn nhiều mkdirlệnh mkdir -p very/many/pathsđể tạo bất kỳ thư mục cha nào khi cần. ;)
speakr

Nếu bạn phải làm điều đó thường xuyên, chỉ cần tạo một tập lệnh bash tự động hóa nó. Lấy đối số lưu trữ của bạn và đường dẫn và tệp trong kho lưu trữ nhưupdatezip very/many/path/file.txt file.txt
Depado

1
7z có một tùy chọn cho việc này 7z a yourfile.7z -sivery/many/paths/file.txt < file.txtnhưng thật không may, khi tôi thử điều này với zip, nó sẽ xảy ra lỗi. Vì vậy, tính năng này chỉ hoạt động với 7z chứ không phải với zip / tar :(
frostschutz

Có thể trùng lặp Thêm tệp vào một đường dẫn khác (nhưng câu hỏi chưa nhận được câu trả lời nâng cao hoặc được chấp nhận).
lgeorget

Câu trả lời:


2

Sử dụng thư viện zipfile của Python?

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

Đồng ý. Hiện tại không có '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

Hãy thêm '/ etc / motd' dưới dạng 'text / motd' vào zipfile hiện có ...

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

Thư viện zipfile đủ đẹp để tạo '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

.. và nó dường như chứa đựng những gì tôi muốn ...

Hãy kiểm tra nó bằng cách giải nén nó ra thiết bị xuất chuẩn ...

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

Khỏe!

Bây giờ chúng tôi thêm một tập tin thứ 2 ...

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

Một cách tôi muốn đề xuất là giải nén, di chuyển tệp và sau đó nén lại.

Ví dụ: giả sử chúng ta có tệp zip này:

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

Để giải nén tệp, trước tiên hãy tạo một thư mục /tmp. Sau đó, chúng tôi sẽ thực hiện các hành động sau:

  1. Giải nén foo.zipvào thư mục tạm thời của chúng tôi
    d=$(mktemp -t -d foo.zip.XXXXXX) && unzip -d $d foo.zip
  2. Di chuyển tệp đến đường dẫn mới (liên quan đến thư mục tạm thời $d)
    mv ${d}/file.txt ${d}/very/many/paths/
  3. Trong subshell: cdđể tạm thời dir & Giải nén mọi thứ vào một tệp zip mới
    ( cd $d && zip -r foo.zip ./* )
  4. Di chuyển tệp zip mới từ thư mục tạm thời để thay thế tệp cũ
    mv ${d}/foo.zip ./
  5. Dọn dẹp :-)
    rm -rf ${d}

Đúng, nhưng không hiệu quả, zip không phải là một định dạng nén vững chắc và cho phép thêm và xóa nội dung mà không cần giải nén. Tuy nhiên, nếu việc thêm tệp và thậm chí toàn bộ cấu trúc thư mục vào tệp zip xảy ra thường xuyên, có thể có một số cách khác.
orion

Người ta biết rằng định dạng .zip không ở đâu gần tỷ lệ nén cao nhất ngoài kia. Có nhiều sự lựa chọn tốt hơn như 7z ngày nay. Tuy nhiên, định dạng .zip có thể là định dạng di động nhất do hỗ trợ được tích hợp vào một số Hệ điều hành nhất định ;-). Thêm vào đó, OP đặc biệt yêu cầu một ví dụ định dạng .zip trong câu hỏi.
TrinitronX

-1

Bạn có thể sử dụng Ant cho điều đó.

Tạo một tệp có tên 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>

Sau đó, trong cùng một thư mục build.xml, bạn có thể chạy nó bằng cách sử dụng cái gì đó như:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.