7

I have a file named 'sourceZip.zip'

This file ('sourceZip.zip') contains two files:

'textFile.txt'

'binFile.bin'


I also have a file named 'targetZip.zip'

This file ('targetZip.zip') contains one file:

'jpgFile.jpg'


In linux, what bash command shall I use to copy both files ('textFile.txt', 'binFile.bin') from the source archive ('sourceZip.zip') straight into the second archive ('targetZip.zip'), so that at the end of the process, the second archive ('targetZip.zip') will include all three files?

(ideally, this would be done in one command, using 'zip' or 'unzip')

4 Answers 4

5

Using the usual command-line zip tool, I don't think you can avoid separate extraction and update commands.

source_zip=$PWD/sourceZip.zip
target_zip=$PWD/targetZip.zip
temp_dir=$(mktemp -dt)
( cd "$temp_dir"
  unzip "$source_zip"
  zip -g "$targetZip" .
  # or if you want just the two files: zip -g "$targetZip" textFile.txt binFile.bin
)
rm -rf "$temp_dir"

There are other languages with more convenient zip file manipulation libraries. For example, Perl with Archive::Zip. Error checking omitted.

use Archive::Zip;
my $source_zip = Archive::Zip->new("sourceZip.zip");
my $target_zip = Archive::Zip->new("targetZip.zip");
for my $member ($source_zip->members()) {
          # or (map {$source_zip->memberNamed($_)} ("textFile.txt", "binFile.bin"))
    $target_zip->addMember($member);
}
$target_zip->overwrite();

Another way is to mount the zip files as directories. Mounting either of the zip files is enough, you can use zip or unzip on the other side. Avfs provides read-only support for many archive formats.

mountavfs
target_zip=$PWD/targetZip.zip
(cd "$HOME/.avfs$PWD/sourceZip.zip#" &&
 zip -g "$target_zip" .)  # or list the files, as above
umountavfs

Fuse-zip provides read-write access to zip archives, so you can copy the files with cp.

source_dir=$(mktemp -dt)
target_dir=$(mktemp -dt)
fuse-zip sourceZip.zip "$source_dir"
fuse-zip targetZip.zip "$target_dir"
cp -Rp "$source_dir/." "$target_dir" # or list the files, as above
fusermount -u "$source_dir"
fusermount -u "$target_dir"
rmdir "$source_dir" "$target_dir"

Warning: I typed these scripts directly in my browser. Use at your own risk.

0
4

Not sure about adding to archive, but you can always recreate one

unzip a.zip -d tmp
unzip b.zip -d tmp
zip -r c.zip tmp

First two lines unpack archives into tmp dir and the third one packages it back.

3

There's a tool called zipmerge that can do it. The description from the man page is:

zipmerge merges the source zip archives source-zip into the target zip archive target-zip. By default, files in the source zip archives over- write existing files of the same name in the target zip archive.

0

I'm going to say straightaway that I don't know the answer, from a practical point.

However, from a theoretical viewpoint, surely you'd have to unzip and re-zip the files. You can't just move them in zipped-state, surely? For a start, you'd have to assume that both zip files had identical settings with regard to compression mode and level.

You could possibly chain the unzip and zip commands together, but then that becomes a question of juggling around the commands on the command line, for which I shall defer to the *nix experts.

I stand very ready to be corrected.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .