11

I have a file that placed in the following directory:

folder_A/another_folder_A/file_to_add.xml

Now, what I want to do is simply add the file to a folder in an existing zip archive.

For example this is my zip content:

my_zip.zip/folder_B/another_folder_B

How can I add the file_to_add.xml to the another_folder_B?

my_zip.zip/folder_B/another_folder_B/file_to_add.xml

I don't want to create folders with the same names and add them. Is there a command that allow me to do that?

Anthon
  • 79,293
Daniel-B
  • 111

2 Answers2

2

Do not know a way to do this by 7z or zip tools directly. But, guess most libraries like perl, python etc has a zip module. You can't, however do it in Bash.


Here is a simple example in PHP:

Test case:

$ mkdir -p A/B C/D E/F
$ touch A/B/f1.txt C/D/f2.txt E/F/f3.txt
$ tree .
.
├── A
│   └── B
│       └── f1.txt
├── C
│   └── D
│       └── f2.txt
├── E
│   └── F
│       └── f3.txt

$ ./php_zip -v out.zip -p x/y //f?.txt $ 7z l out.zip

Listing archive: out.zip

Path = out.zip Type = zip Physical Size = 310

Date Time Attr Size Compressed Name


2013-04-28 10:24:36 ..... 0 0 x/y/f1.txt 2013-04-28 10:24:36 ..... 0 0 x/y/f2.txt 2013-04-28 10:24:36 ..... 0 0 x/y/f3.txt


                                 0            0  3 files, 0 folders


Usage:

./php_zip [-v|--verbose] archive.zip [<-p|--path> archive-path] files ...

--verbose Verbose; print what is added and where. archive.zip Output file. Created if does not exist, else extended. --path Target path in zip-archive where to add files. If not given source path's are used. files 0+ files.

If -P or --Path (Capital P) is used empty directory entries is added as well.


Code:

(Have not coded PHP in a long time. The code is anyhow only meant as an example to be expanded or other.)

#!/usr/bin/php
<?php

$debug = 0;

function usage($do_exit=1, $ecode=0) { global $argv; fwrite(STDERR, "Usage: " . $argv[0] .
" [-v|--verbose] archive.zip" . " [<-p|--path> archive-path]" . " files ...\n" );

if ($do_exit)
    exit($ecode);

}

$zip_eno = array( ZIPARCHIVE::ER_EXISTS => "EXISTS", ZIPARCHIVE::ER_INCONS => "INCONS", ZIPARCHIVE::ER_INVAL => "INVAL", ZIPARCHIVE::ER_MEMORY => "MEMORY", ZIPARCHIVE::ER_NOENT => "NOENT", ZIPARCHIVE::ER_NOZIP => "NOZIP", ZIPARCHIVE::ER_OPEN => "OPEN", ZIPARCHIVE::ER_READ => "READ", ZIPARCHIVE::ER_SEEK => "SEEK" );

function zip_estr($eno) { switch ($eno) { case ZIPARCHIVE::ER_EXISTS: } }

if ($debug) print_r($argv);

if ($argc > 1) if ($argv[1] == "-h" || $argv[1] == "--help") usage();

if ($argc < 3) usage(1, 1);

$verbose = 0; $path = ""; $add_dir = 0; $zip = new ZipArchive(); $i = 1;

if ($argv[$i] == "-v" || $argv[$i] == "--verbose") { if ($argc < 4) usage(1, 1); $verbose = 1; ++$i; }

$zip_flag = file_exists($argv[$i]) ? ZIPARCHIVE::CHECKCONS : ZIPARCHIVE::CREATE;

if (($eno = $zip->open($argv[$i++], $zip_flag)) !== TRUE) { fwrite(STDERR, "ERR[$eno][$zip_eno[$eno]]: ". "Unable to open archive " . $argv[$i - 1] . "\n" ); exit($eno); }

if ( $argv[$i] == "-P" || $argv[$i] == "--Path" || $argv[$i] == "-p" || $argv[$i] == "--path" ) { if ($argc - $i < 2) usage(1, 1); $path = $argv[$i + 1]; if (substr($path, -1) !== "/") $path .= "/"; if ($argv[$i][1] == "P") $zip->addEmptyDir($path); $i += 2; }

$eno = 0;

for (; $i < $argc; ++$i) { if ($path !== "") $target = $path . basename($argv[$i]); else $target = $argv[$i];

if ($verbose)
    printf(&quot;Adding %s to %s\n&quot;, $argv[$i], $target);
if (!$zip-&gt;addFile($argv[$i], $target)) {
    fwrite(STDERR, &quot;Failed.\n&quot;);
    $eno = 1;
}

}

$zip->close();

exit($eno); ?>

Runium
  • 28,811
0

If your directories have the same name inside and outside the zipfile, it's pretty easy. In the directory containing folder, you can do zip my_zip.zip folder -r.

If your structure inside and outside the zipfile is not exactly the same, you'll have to manually recreate it before applying the previous method. As far as I can tell (and after checking in the man page for interesting yet rather ignored functions like update (-u)) there is no way to put a file into an arbitrary directory inside a zipfile.

lgeorget
  • 13,914