0

I would like to zip all files in a given folder but none of the directories: any idea on how to do it?

e.g. directory X contains files F1 and F2 and directories D1 and D2.
How can I zip directory X to only have F1 and F2 and not D1 and D2.

1
  • Please use proper syntax
    – mattia.b89
    Commented May 1, 2020 at 20:24

4 Answers 4

2

One way to approach it would be to use zip's exclusion option:

zip /path/to/zip/file.zip /path/to/given/folder/* -x /path/to/given/folder/*/

This tells zip to archive everything in /path/to/given/folder but also to exclude everything in that folder that is a directory. Here it's the shell doing the work, via wildcards, to expand the wildcard that ends in slash to the list of directories in that folder. If you had dotfiles in that directory, you'd have to expand them separately -- and also exclude any "dot directories".

2

With GNU find or compatible, assuming there are no filenames containing newlines:

find X -maxdepth 1 -type f | zip -nw -@ X.zip

The -@ option takes a list of files from stdin, one file per line. -nw (or --no-wild) turns off wildcard expansion by zip, to avoid problems with filenames containing *, ? or [ characters.

3
  • smart ! there is no easier way ?? A flag, a wildcard, etc ? Commented May 1, 2020 at 19:51
  • Maybe with zsh? I don't know a faster way, let's wait for other answers.
    – Freddy
    Commented May 1, 2020 at 19:53
  • @user3360735 it's already extremely compact and optimised Commented Jan 17, 2023 at 11:11
0

With zsh,

zip -nw X.zip X X/*(ND.)

Would store X and the regular files (with the . glob qualifier including hidden ones with D) in it into the X.zip compressed archive in lexical order.

Instead of . which selects regular files only, you could use ^/ which selects files of any type except directories, including symlink, fifo, devices, sockets. But of those, the zip format (which is not much of a Unix format) can only store symlinks and fifos (named pipes), and you'd need to pass the --symlinks and --fifo option to zip. You could also use .,@,p to select only regular, symlinks and named pipes:

zip --symlinks --fifo -nw X.zip X/*(ND.,@,p)
-1

In case we want to escape a specific subfolder at time to zip, we need to scape the * with a backslash (\), so that it is treated as a literal character by the shell (rather than being expanded into a list of files), in this way:

zip /path/to/zip/file.zip /path/to/given/folder/* -x /path/to/given/folder/subfolder/\*

Hope this help!

2
  • If the * is not escaped or quoted somehow, it will be expanded by the shell. However, this would still work correctly since the -x option takes one or several patterns. The trailing / is needed to only match directories.
    – Kusalananda
    Commented Mar 17, 2023 at 11:46
  • Yes, you're right... Sorry, I tried and posted my answer for the case of escaping a specific subfolder, I missed that the question mentioned 'all subfolders'. Editing my comment, in case this still helpful for someone. Commented Mar 17, 2023 at 14:32

You must log in to answer this question.

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