I want to update/freshen a file in a zip archive with the contents of stdin
. So far I haven't been able to find a way to tell the zip
command that the contents of stdin
correspond to a particular file.
E.g. (the last line is how I'd expect it to work but it doesn't make any changes to the zip file):
~/D/tmp ♪ unzip -l sample.odt # an odt file is actually a zip file
Archive: sample.odt
Length Date Time Name
-------- ---- ---- ----
39 01-06-10 00:46 mimetype
0 01-06-10 00:46 Configurations2/statusbar/
0 01-06-10 00:46 Configurations2/accelerator/current.xml
0 01-06-10 00:46 Configurations2/floater/
0 01-06-10 00:46 Configurations2/popupmenu/
0 01-06-10 00:46 Configurations2/progressbar/
0 01-06-10 00:46 Configurations2/menubar/
0 01-06-10 00:46 Configurations2/toolbar/
0 01-06-10 00:46 Configurations2/images/Bitmaps/
3374 01-06-10 00:46 content.xml
11837 01-06-10 00:46 styles.xml
957 01-06-10 00:46 meta.xml
1060 01-06-10 00:46 Thumbnails/thumbnail.png
8086 01-06-10 00:46 settings.xml
1889 01-06-10 00:46 META-INF/manifest.xml
-------- -------
27242 15 files
~/D/tmp ♪ unzip -p sample.odt meta.xml > tmp.xml
~/D/tmp ♪ # modify tmp.xml somehow
~/D/tmp ♪ cat tmp.xml | zip sample.odt -u meta.xml
EDIT (Taken from my comment below): I can't just load the file directly into the zip file by referencing the new version because the initial extraction is never being redirected to a file in my actual situation. Instead to a database where it undergoes some text processing in a background queue. It is then substituted back into the document on demand.
Is there a reason you can't just do:
Then you don't have to worry about doing wierd gyrations to pipeline everything back in
In response to you comment, the only two suggestions I can think of is
a) Write the file out to a random temp directory
/tmp/<random_number>/meta.xml
then do azip sample.odt -u /tmp/<random_number>/meta.xml
b) Ask on Stack overflow if there is a programatic way to manipulate your zip file.
The
zip
man page describes how a single dash can be used to represent STDIN or STDOUT in a command-line, sozip
can be used in a pipeline.Look for Streaming input and output in the man page.
BUT since you're using STDIN and not specifying a file name with this method, it's not going to work as you'd like with muti-file zip archives.
As the mention of
gunzip
in the man page suggests, it's meant for archives containing single files.In the same way
gzip filename
produces filename.gz,zip
can produce filename.zip except that zip requires you to explicitly name the zip file.HERE'S a relevant new post on SO. I nearly fell off my chair when I saw this.