177

I have a directory called folder that looks like this:

folder
      -> root_folder
                    -> some files

I want to zip this directory into zipped_dir, I tried:

zip -r zipped_dir.zip folder/*

But this generates a ZIP that looks like this:

zipped_dir
          -> folder
                   -> root_folder
                                 -> some files

in other words, it's including the directory whose contents I want to zip. How can I exclude this parent directory from the ZIP, without moving anything?

IE I would like this end result:

zipped_dir
          -> root_folder
                        -> some files
1
  • Juicy, if you find my answer helpful you may consider mark it as accepted :) May 9 at 17:20

6 Answers 6

156

Try to use this command (you will get the idea)

cd folder; zip -r ../zipped_dir.zip *

Maybe there is other way, but this is fastest and simplest for me :)

13
  • 2
    this works perfectly doing that trick. note: it will do a chroot . Aug 25, 2016 at 14:24
  • 7
    @TobiasKolb, maybe you do not read the question. OP do not want to have folder in to the stored path in zip. Sep 12, 2018 at 10:55
  • 3
    Seems the only way to do
    – Robert
    Sep 13, 2018 at 2:32
  • 3
    this won't add hidden files
    – Gus
    Nov 25, 2018 at 0:53
  • 1
    @PabloDiaz, in my example cd - will do the work (only one command) :) Or cd .. Feb 15, 2019 at 18:37
83

Use -j; for example: zip -r -j zipped_dir.zip folder/*

It won’t zip 'root_folder'.

6
  • 8
    I get an error with this one if I have two files of the same name.
    – Chris
    Dec 1, 2016 at 22:06
  • 38
    OP probably wants only the parent directory removed, not all of them.
    – tokland
    Mar 13, 2017 at 10:13
  • 6
    it flatten's child directory files as well. May 10, 2018 at 7:19
  • 14
    the -j option eliminate all directory info and only save files. That is, to store all files under one directory in a "flat" way.
    – Robert
    Sep 13, 2018 at 2:34
  • 10
    This should not be the accepted answer Oct 13, 2019 at 18:14
16
zip -r -D zipped.zip *

-D instructs zip to not create directories.

4
  • this is the neatest solution.
    – Haider
    Jun 11, 2020 at 4:22
  • doesn't seem to be a valid option in mac os zip
    – dtech
    Jul 16, 2020 at 8:30
  • 1
    Works in macos. Don't forget that using * will exclude hidden files, so I ended up using .: zip -D -r ../archive.zip . Sep 10, 2020 at 13:55
  • This doesn't work for the simple reason that files aren't directories. Zip stores files with full filenames like folder/root_folder/some files/filename.txt (note that the filename contains slashes). -D just prevents directory-file entries like folder/root_folder/some files to be included., but the files in that directory are still included. Jul 28, 2021 at 9:57
11

This is what works for me:

7z a zipped.zip ./rootDir/*

It will create a zip archive with root: any files/directories inside rootDir. e.g

zipped.zip:
     file1.txt
     otherdir/
        file2.txt

Hidden files:

As correctly pointed on @Shiva Wu's comment the above does not include hidden files.

This is also the case for the rest of the answers (at least the ones which preserve directory structure). One solution is to explicitly add the hidden paths wildcard.

# The command below will include all files and directories starting with a dot.
7z a zipped.zip ./rootDir/* ./rootDir/.[!.]*

OR

# Same as above in one argument
7z a zipped.zip ./rootDir/{*,.[!.]*}

result:

zipped.zip:
     file1.txt
     .hiddenfile1.txt
     .hiddendir/
        file3.txt
     otherdir/
        file2.txt
4
  • 1
    The best answer for me need.
    – Marcin
    Jan 1, 2020 at 2:27
  • 2
    That should probably be the accepted answer and definitely higher up. No changing directories, just nice and straightforward.
    – geo909
    Mar 31, 2020 at 10:49
  • This doesn't deal with ./rootDir/.xxx. It should be something like .rootDir/{.*,*}
    – Shiva Wu
    May 11, 2020 at 1:50
  • @ShivaWu Correct! I have updated my answer. Note: The wildcard that works (at least on bash) is slightly different to what you provided.
    – Marinos An
    May 11, 2020 at 10:53
1

Note that you may get an error (bash: /usr/bin/zip: Argument list too long) when using Romeo Ninov's answer if you are zipping many thousands of files. To avoid this, use a . instead of a *, like so:

cd folder
zip -r ../zipped_folder.zip .
1

I use -r option, the "zip filename" and the list of items I want to add into it. Refering to --help option we get:

zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]

You can go into folder that contains the files and directories you want to zip in. The run the command:

zip -r filename.zip ./*

The result is a filename.zip containing everything into the directory you ran the command.

Adding a command for hidden files, we can use ls -a from shell put after zip command (already in the directory that contains your desired files):

FILES=$(ls -a)
zip -r filename.zip $FILES

For fish users, just change FILES=$(ls -a) to set FILES (ls -a).

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