21

I have the following folder structure

folder
|
|--foo.txt
|
|--sub_folder
   |
   |--bar.txt

I want to zip the content (files and sub folders) of folder without including the root folder in the zip.

I have tried command

zip -r package.zip folder

But this includes the root folder. Also tried the following form

zip -j -r package.zip folder

But this will flatten all the directory structures and just include the files. How do I preserve the internal directory structure but ignore the parent folder?

4 Answers 4

35

zip stores paths relative to the current directory (when it is invoked), so you need to change that:

(cd folder && zip -r "$OLDPWD/package.zip" .)

&& ensures that zip only runs if the directory was correctly changed, and the parentheses run everything in a subshell, so the current directory is restored at the end. Using OLDPWD avoids having to calculate the relative path to package.zip.

0
2
zip -r package.zip folder/*

The above command will zip all files and sub folders under folder directory (It will ignore the parent directory for folder)

1
  • 1
    This will store the folder/ path in the archive, which the OP doesn’t want. It will also ignore any hidden files inside folder. Oct 7, 2021 at 9:58
1

To add to other answers, for scripts, you could use

pushd folder; zip -r ../package.zip .; popd

pushd changes the directory much like cd, but remembers the previous one, and popd restores the last remembered directory.

In this case it's equivalent to removing the parentheses (which spawn a new shell) and adding ; cd .. at the end of the command suggested by Stephen.

Note: I would add this as a comment, but I can't because I do not have enough reputation.

7
  • Stephen’s answer is fine as it is; it doesn’t need anything added to it.  Do you believe that your approach is better than his?  Why?  … … … … … … … … … … … … … … … … … … Please do not respond in comments; edit your answer to make it clearer and more complete. Aug 15, 2022 at 22:54
  • It's a nice trick that is useful especially when writing scripts as I mentioned in the first sentence.
    – Harvastum
    Aug 16, 2022 at 14:30
  • It's not necessarily better, but can make your life easier. For example, if you go a few directories down but need to back later in the script, it's easier to just popd than to cd ../../../../. It's easy to get the number of levels you have to go up wrong. Can't make that mistake with popd though. Thanks for coming to my speech inside a comment!
    – Harvastum
    Aug 16, 2022 at 14:39
  • Well, my point is that you don’t seem to fully understand Stephen’s answer.  He is using parentheses, not as English punctuation, but as shell syntax, causing the commands within the parentheses to run in a subshell.  So the cd changes the working directory of the subshell but not the main shell.  To borrow your language, the main shell process remembers what directory it is in, by staying there; it’s still there when the subshell terminates, so nothing needs to be restored. … (Cont’d) Aug 16, 2022 at 19:23
  • (Cont’d) …  If Stephen’s answer is a line in a script, the command on the next line (or even after a ;) is executed in the directory above “folder”.  You can try this yourself with (pwd; cd /; pwd); pwd (from the command line or in a script).  That’s why I said “Stephen’s answer is fine as it is; it doesn’t need anything added to it.” — it doesn’t need to cd ... Aug 16, 2022 at 19:24
0

You need to use -j or --junk-paths in the command to avoid parent directory and zip only the file. Zip command reference

-j
--junk-paths

Store just the name of a saved file (junk the path), and do not store directory names. By default, zip will store the full path (relative to the current directory).

Reference of the answer

1
  • This flattens all the subfolders too which is not what the op wanted. Your output will contain the foo.txt and bar.txt files without the subfolder. Sep 12, 2023 at 17:16

You must log in to answer this question.

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