zip — quick reference
Create and update archives
| When to use | Command |
|---|---|
| Zip all files in the current directory | zip archive.zip * |
| Zip a directory recursively | zip -r archive.zip /path/to/dir |
| Zip specific files | zip archive.zip file1 file2 |
| Exclude files by pattern | zip archive.zip * -x '*.log' |
| Store filenames only (drop path) | zip -j archive.zip /path/to/files/* |
| Freshen changed entries in existing zip | zip -f archive.zip files |
| Append files to existing archive | zip -g archive.zip newfile |
| Move files into zip (delete originals after) | zip -m archive.zip files |
Compression and format
| When to use | Command |
|---|---|
| Fastest compression (level 1) | zip -1 -r archive.zip dir/ |
| Best deflate compression (level 9) | zip -9 -r archive.zip dir/ |
| Store without compression | zip -0 archive.zip file |
| Use bzip2 method inside zip | zip -Z bzip2 archive.zip file |
| Split archive at size (e.g. 1 MiB) | zip -s 1m archive.zip bigfile |
| Quiet output | zip -q -r archive.zip dir/ |
Security and metadata
| When to use | Command |
|---|---|
| Encrypt with password (prompt) | zip -e archive.zip files |
| Encrypt with password on command line | zip -P password archive.zip files |
| Preserve symbolic links as links | zip -y archive.zip link files |
Inspect and maintain
| When to use | Command |
|---|---|
| List archive contents | zip -sf archive.zip |
| Test archive integrity | zip -T archive.zip |
| Delete entries from archive | zip -d archive.zip path/in/zip |
| Copy entries to new archive | zip archive.zip --copy --out new.zip entries |
unzip (extract)
| When to use | Command |
|---|---|
| Extract to current directory | unzip archive.zip |
| Extract to a directory | unzip archive.zip -d /path/to/dir |
| List without extracting | unzip -l archive.zip |
| Test archive | unzip -t archive.zip |
| Extract with password | unzip -P password archive.zip |
Help
| When to use | Command |
|---|---|
| Show zip usage | zip --help |
| Show zip version | zip -v |
zip — command syntax
Synopsis from zip --help on Ubuntu 25.04 (zip 3.0):
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]Default action: add or replace entries in zipfile from list. If zipfile is omitted, zip compresses stdin to stdout. Pair with the unzip command to extract. No root needed for files you own.
zip — command examples
Essential Zip a folder recursively
Use -r so directories and subdirectories are stored, not just an empty directory entry.
Run the commands:
mkdir -p /tmp/zip-lab/src/sub
echo 'line one' > /tmp/zip-lab/src/a.txt
echo 'line two' > /tmp/zip-lab/src/sub/b.txt
cd /tmp/zip-lab/src
zip -r /tmp/zip-lab/archive.zip .
zip -sf /tmp/zip-lab/archive.zipSample output:
adding: a.txt (stored 0%)
adding: sub/ (stored 0%)
adding: sub/b.txt (stored 0%)
Archive contains:
a.txt
sub/
sub/b.txt
Total 3 entries (18 bytes)Remove the lab with rm -rf /tmp/zip-lab when done.
Essential Zip a tree but exclude paths
-x accepts patterns after the file list. Quote globs so the shell does not expand them too early.
Run the commands:
cd /tmp/zip-lab/src
zip /tmp/zip-lab/exclude.zip . -r -x 'sub/*'
zip -sf /tmp/zip-lab/exclude.zipSample output:
adding: a.txt (stored 0%)
Archive contains:
a.txt
Total 1 entries (9 bytes)Multiple exclusions: zip -r out.zip . -x '*.log' -x 'tmp/*'.
Common Store only filenames (-j junk paths)
Without -j, zip keeps relative paths (src/sub/b.txt). With -j, all entries land at the top level of the archive.
Run the commands:
cd /tmp/zip-lab/src
zip -j /tmp/zip-lab/junkpaths.zip a.txt sub/b.txt
zip -sf /tmp/zip-lab/junkpaths.zipSample output:
adding: a.txt (stored 0%)
adding: b.txt (stored 0%)
Archive contains:
a.txt
b.txt
Total 2 entries (18 bytes)Useful when recipients should extract flat files without recreating your source tree.
Common List a zip and extract with unzip
zip -sf and unzip -l show members without unpacking. unzip restores files.
Run the commands:
unzip -l /tmp/zip-lab/archive.zip
mkdir -p /tmp/zip-lab/extract
unzip -q /tmp/zip-lab/archive.zip -d /tmp/zip-lab/extract
find /tmp/zip-lab/extract -type fSample output:
Archive: /tmp/zip-lab/archive.zip
Length Date Time Name
--------- ---------- ----- ----
9 ... a.txt
9 ... sub/b.txt
--------- -------
18 2 files
/tmp/zip-lab/extract/a.txt
/tmp/zip-lab/extract/sub/b.txtCommon Update changed files — freshen and grow
-f replaces entries that changed on disk; -g adds new names to an existing archive.
Run the commands:
echo v2 >> /tmp/zip-lab/src/a.txt
cd /tmp/zip-lab/src
zip -f /tmp/zip-lab/archive.zip a.txt
echo new > /tmp/zip-lab/src/new.txt
zip -g /tmp/zip-lab/archive.zip new.txt
zip -sf /tmp/zip-lab/archive.zipSample output:
freshening: a.txt (stored 0%)
adding: new.txt (stored 0%)Run freshen from the same working directory you used when paths were stored, or paths may not match.
Common Remove files from an archive without extracting
-d deletes matching paths inside the zip file.
Run the commands:
zip -d /tmp/zip-lab/archive.zip sub/b.txt
zip -sf /tmp/zip-lab/archive.zipSample output:
deleting: sub/b.txt
Archive contains:
a.txt
sub/
new.txtWildcards work: zip -d archive.zip '*.tmp'.
Advanced Password-protected zip and test extract
-e prompts for a password; -P sets it on the command line (visible in shell history — avoid on shared systems).
Run the commands:
cd /tmp/zip-lab/src
zip -P testpass /tmp/zip-lab/enc.zip a.txt
unzip -P testpass -t /tmp/zip-lab/enc.zipSample output:
adding: a.txt (stored 0%)
Archive: /tmp/zip-lab/enc.zip
testing: a.txt OK
No errors detected in compressed data of /tmp/zip-lab/enc.zip.Zip encryption is weak by modern standards — use GPG or age for sensitive data.
Advanced Preserve symlinks and use bzip2 compression
-y stores symlinks as links. -Z bzip2 uses bzip2 instead of deflate (receiver needs a recent unzip).
Run the commands:
Point a short command name at the install path with ln -sf; the create symbolic link on Linux covers -s, -f, and safe targets under /usr/local/bin.
ln -sf a.txt /tmp/zip-lab/src/link
cd /tmp/zip-lab/src
zip -y /tmp/zip-lab/symlink.zip link a.txt
zip -Z bzip2 /tmp/zip-lab/bz2.zip a.txt
unzip -t /tmp/zip-lab/bz2.zipSample output:
adding: link (stored 0%)
adding: a.txt (bzipped 9%)
No errors detected in compressed data of /tmp/zip-lab/bz2.zip.Advanced Split a large zip into fixed-size pieces
-s SIZE creates archive.z01, archive.z02, … plus archive.zip for the last segment. Extract with zip -s 0 split.zip --out combined.zip or zip -FF.
Run the commands:
dd if=/dev/zero of=/tmp/zip-lab/bigfile bs=1M count=3 status=none
cd /tmp/zip-lab
zip -q -s 1m /tmp/zip-lab/split.zip bigfile
ls -lh /tmp/zip-lab/split*Sample output (sizes vary slightly):
-rw-r--r-- 1 root root 1.0M ... split.z01
-rw-r--r-- 1 root root 1.0M ... split.z02
-rw-r--r-- 1 root root 1.0M ... split.zipUseful when email or legacy media caps individual file size.
zip — when to use / when not
| Use zip when | Use something else when |
|---|---|
|
zip vs tar.gz
| zip | tar.gz | |
|---|---|---|
| Format | PKZIP (single .zip file) | tar bundle + gzip compression |
| Windows friendly | Native Explorer support | Needs 7-Zip or similar |
| Permissions / symlinks | Limited, limited | tar preserves more metadata |
| Random access / delete entry | zip -d, zip -g |
Must rebuild archive |
| Typical command | zip -r a.zip dir |
tar czf a.tar.gz dir |
Related commands
| Command | One line |
|---|---|
| zip | Create and maintain .zip archives (this page) |
| tar | Tape-archive format common on Linux |
Browse the full index in our Linux commands reference.
zip — interview corner
What is the difference between zip and unzip?
zip creates and updates .zip archives — add files, compress, encrypt, delete members.
unzip reads archives — list (-l), test (-t), extract to disk (-d for target directory).
They are separate programs from Info-ZIP; install both packages on minimal servers if you exchange zip files.
A strong answer is:
"zip builds and edits PKZIP archives; unzip lists, tests, and extracts them — complementary tools, not two modes of one binary."
How do you zip a folder in Linux?
Change to the parent or pass the directory path with -r (recursive):
zip -r backup.zip /path/to/projectWithout -r, zip stores an empty directory entry. Use -x to skip patterns and -j to flatten paths.
A strong answer is:
"zip -r archive.zip directory — -r walks subdirectories; -x excludes patterns, -j drops path prefixes."
How do you zip everything except certain files?
Put exclusions after the file list with -x:
zip -r out.zip project/ -x 'project/*.log' -x 'project/tmp/*'Quote globs so the shell does not expand them before zip sees the pattern.
A strong answer is:
"Use -x after the paths to archive — quoted globs like '.log' or 'build/' so zip skips matching entries."
How do you create a password-protected zip?
Interactive: zip -e archive.zip files (prompts twice).
Scripted (less safe): zip -P secret archive.zip files.
Extract with unzip -P secret archive.zip. Know that classic zip crypto is weak for serious secrets.
A strong answer is:
"zip -e for prompted password; unzip with -P to test — fine for casual protection, not for strong security."
When would you pick zip over tar.gz?
Pick zip when the consumer is on Windows, you need in-place entry delete/update, or the spec demands .zip.
Pick tar.gz (or tar.xz) for Linux backups where permissions, symlinks, and streaming matter.
A strong answer is:
"zip for cross-platform .zip and editable archives; tar.gz for Unix-native metadata and typical Linux backup pipelines."
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
zip: command not found |
Package missing | sudo apt install zip unzip |
| Empty directory in zip only | Forgot -r |
zip -r archive.zip dir/ |
zip error: Nothing to do! |
No files matched or bad split syntax | Check paths; for split use zip -s SIZE archive.zip files |
| Freshen updates nothing | Wrong cwd vs stored paths | Run from original directory or re-add with full paths |
unzip password fails |
Wrong crypto or truncated file | Re-create with -e; verify with unzip -t |
| bzip2 zip won't extract | Old unzip | Upgrade unzip or use deflate (-9) instead |
zip -m deleted sources |
Move mode | Restore from backup; test with -T before -m on important data |

