I want to zip a folder recursively, but exclude certain directories (temp/.hidden in the example below). I want the zip file to have a top level folder which would be temp in the example below, hence my working directory is temp.

mkdir -p temp/subdir
touch temp/subdir/keepthisfile.txt
touch temp/excludethisfile.txt
mkdir temp/.hidden
touch temp/.hidden/exclude.txt
cd temp/

Code I have to achieve what I want is either

zip -r temp.zip ../temp/ -x ../temp/excludethisfile.txt ../temp/.hidden/* ../temp/.hidden/

Or more concisely (syntax gleaned from elsewhere online)

zip -r temp.zip ../temp/ -x ../temp/excludethisfile.txt ../temp/*.hidden*

I can see why this would work, but I can't see why the code below doesn't do the same thing (i.e. why do I need ../temp/*.hidden* rather than just ../temp/.hidden*?)

zip -r temp.zip ../temp/ -x ../temp/excludethisfile.txt ../temp/.hidden*

Your shell expands ../temp/.hidden* into ../temp/.hidden before executing Zip; this pattern no longer matches ../temp/.hidden/exclude.txt. You should quote the pattern, as recommended by Zip manual page:

zip -r temp.zip ../temp/ -x ../temp/excludethisfile.txt '../temp/.hidden*'

Thanks! Having now properly RFTM, my man pages suggest

The backslash avoids the shell filename substitution, so that the name matching is performed by zip at all directory levels.

So the code becomes zip -r temp.zip ../temp/ -x ../temp/exclude.txt ../temp/.hidden/\*

I prefer the quoting though :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.