zip and unzip¶
Format: .zip · Algorithm: per-file DEFLATE (store, bzip2, LZMA, zstd and others are allowed by the spec) · First released: 1989 (Phil Katz, PKWARE)
ZIP is the one archive format every operating system opens natively, which makes it the right choice for handing files to non-technical users. Each member is compressed separately, so you get fast random access but a worse ratio than a solid tarball on many small similar files.
Many other formats are ZIP files underneath: .jar, .war, .apk (Android), .docx, .xlsx, .pptx, .odt, .epub, and Python .whl.
On Linux, zip and unzip come from the Info-ZIP project.
Creating archives¶
zip -r archive.zip src_dir/
zip -r -9 archive.zip src_dir/ # max compression
zip -r -0 archive.zip src_dir/ # store only
zip -r archive.zip src_dir/ -x '*.git*' '*/node_modules/*'
zip -r -y archive.zip src_dir/ # store symlinks as links
zip -r -n .jpg:.png:.mp4 archive.zip media/ # don't recompress these
zip -j flat.zip dir/*/*.txt # junk paths
zip -r -s 100m split.zip big_dir/ # 100 MB volumes
Modifying archives¶
zip -u archive.zip changedfile # update changed / add new
zip -f archive.zip # freshen: update only existing members
zip -d archive.zip 'path/to/remove' # delete a member
zip -FS -r archive.zip src_dir/ # sync: also remove deleted files
Extracting¶
unzip archive.zip
unzip archive.zip -d /tmp/dest # into a directory
unzip archive.zip 'docs/*' # only matching members
unzip -j archive.zip # junk paths (flatten)
unzip -o archive.zip # overwrite without prompting
unzip -n archive.zip # never overwrite
unzip -p archive.zip file.txt | less # one member to stdout
Inspecting¶
unzip -l archive.zip # list
unzip -v archive.zip # list with ratios and CRCs
unzip -t archive.zip # test integrity
zipinfo archive.zip # detailed listing
zipgrep 'pattern' archive.zip # grep inside members
Encryption (and why it's weak)¶
zip -r -e archive.zip src_dir/ # same as --encrypt; prompts for a password
zipcloak archive.zip # encrypt an existing archive
Info-ZIP's -e uses the legacy ZipCrypto scheme, which is cryptographically broken: known-plaintext attacks recover the keys quickly. Filenames aren't encrypted either. Treat it as a lock that keeps honest people out.
For real protection:
- AES-256 zip via 7-Zip:
7z a -tzip -p -mem=AES256 secret.zip src_dir/(filenames still visible) - 7z with header encryption:
7z a -p -mhe=on secret.7z src_dir/ - age or gpg on a tarball — see encryption
Splitting and joining¶
zip -r -s 100m split.zip big_dir/ # split.z01, split.z02, ..., split.zip
zip -s 0 split.zip --out joined.zip # rejoin
unzip joined.zip
Gotchas¶
- Filename encoding: archives from older Windows tools may use a legacy codepage. Some
unzipbuilds accept-O CP437(or the right codepage) to fix garbled names; 7-Zip and unar often handle this automatically. - Zip64: archives over 4 GiB or with more than 65,535 entries need Zip64. Info-ZIP 3.0 handles it, but very old tools can't read the result.
- Permissions: Unix modes are stored in extra fields and restored by Info-ZIP, but not by every tool. Owners and groups aren't preserved. Use tar for system backups.
- Hard links and special files aren't preserved.
- macOS archives may contain
__MACOSX/and._*files:zip -d archive.zip '__MACOSX/*'removes them. See macOS and Windows. - Zip slip: malicious entries like
../../etc/x. Info-ZIP strips../components, but always list untrusted archives first. See gotchas.
See also¶
- 7-Zip — stronger compression and real encryption
- Universal extractors
- Cheat sheet