How to create a zip with multiple files without sub-folders?
Solution 1:
You can use find
to get the file list and execute zip -j myfiles
to pack them ignoring the paths:
find . -name "d[014]" -exec zip -j myfiles {} +
Example
$ tree
.
├── d0
├── f0
├── f1
│ └── d1
└── f2
└── f3
├── d2
├── d3
└── d4
$ find . -name "d[014]" -exec zip -j myfiles {} +
adding: d1 (stored 0%)
adding: d4 (stored 0%)
adding: d0 (stored 0%)
$ unzip -l myfiles.zip
Archive: myfiles.zip
Length Date Time Name
--------- ---------- ----- ----
0 2017-10-09 10:47 d1
0 2017-10-09 10:48 d4
0 2017-10-09 10:47 d0
--------- -------
0 3 files
However this works for files only, directories will be ignored by zip -j
. To get this working for directories too, say we want to pack d0
, d1
and the whole f3
directory in the above example, the find
line gets a little more complicated:
$ find . \( -name "d[01]" -o -name "f3" \) -exec sh -c 'p=$(pwd); for i in $0 $@; do cd ${i%/*}; zip -ur "$p"/myfiles ${i##*/}; cd "$p"; done' {} +
zip warning: /home/dessert/myfiles.zip not found or empty
adding: d1 (stored 0%)
adding: f3/ (stored 0%)
adding: f3/d3 (stored 0%)
adding: f3/d2 (stored 0%)
adding: f3/d4 (stored 0%)
adding: d0 (stored 0%)
$ unzip -l myfiles.zip
Archive: myfiles.zip
Length Date Time Name
--------- ---------- ----- ----
0 2017-10-11 10:18 d1
0 2017-10-11 10:19 f3/
0 2017-10-11 10:19 f3/d3
0 2017-10-11 10:19 f3/d2
0 2017-10-11 10:19 f3/d4
0 2017-10-11 10:17 d0
--------- -------
0 6 files
Solution 2:
Manually, you can create the zip file and the update it:
zip myfiles d0
(cd f1; zip -u ../myfiles.zip d1)
(cd f2/f3; zip -u ../../myfiles.zip d4)
The parentheses create subshells, and the effect of the cd
only lasts in the subshell, so you don't have to cd
back to the original directory.
If d1
, d2
, etc. are actually files and not directories themselves, then use the -j
option:
-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).
Solution 3:
Using the -j option will remove the path from the file.
zip -j myfiles d0 f1/d1 f2/f3/d4
reference