I want to combine several zip files together using ANT, but I’ve got three restrictions that cause the standard techniques to fail:
- There are files (with known filenames) that I do not want included in the final archive.
- Some of the source archives contain files with the same name, but different capitalization.
- The machine that runs the script uses a case-insensitive filesystem.
To make my problem concrete, here’s an example source archive. I do not know the file names represented by a.txt and A.txt, but I do know the filename b.txt.
$ touch a.txt ; zip src.zip a.txt ; rm a.txt
$ touch A.txt ; zip src.zip A.txt ; rm A.txt
$ touch b.txt ; zip src.zip b.txt ; rm b.txt
$ unzip -l src.zip
Archive: src.zip
Length Date Time Name
-------- ---- ---- ----
0 09-23-11 11:35 a.txt
0 09-23-11 11:35 A.txt
0 09-23-11 11:36 b.txt
-------- -------
0 3 files
And here’s what I want: (everything from the original archive except b.txt)
$ ant
$ unzip -l expected.zip
Archive: expected.zip
Length Date Time Name
-------- ---- ---- ----
0 09-23-11 11:35 a.txt
0 09-23-11 11:35 A.txt
-------- -------
0 2 files
The two techniques that I’ve found recommended on the internet are:
<target name="unzip-then-rezip">
<!-- Either a.txt or A.txt is lost during unzip and
does not appear in out.zip -->
<delete dir="tmp"/>
<delete file="out.zip"/>
<mkdir dir="tmp"/>
<unzip src="src.zip" dest="tmp"/>
<zip destfile="out.zip" basedir="tmp" excludes="b.txt"/>
</target>
<target name="direct-zip">
<!-- Have not found a way to exclude b.txt from out.zip -->
<delete file="out.zip"/>
<zip destfile="out.zip">
<zipgroupfileset dir="." includes="*.zip" />
</zip>
</target>
Using unzip-then-rezip, I loose either a.txt or A.txt because the underlying filesystem is case-insensitive and can not store both files. Using direct-zip seems like the right way to go, but I have yet to find a way to filter out the files I don’t want included.
I’m about to resort to creating my own ANT task to do the job, but I’d much rather use standard ANT tasks (or even ant-contrib), even if there’s a performance or readability penalty.
Have a look at Ant’s Resource Collections, especially things like
restrictthat allow you to filter files (and zip file contents etc.) in quite flexible ways.This snippet seems to what you want (on my machine at least – OSX):
The input file:
The output file: