| name | tar-compression |
| description | Archive and compression commands — tar, gzip, zip, zstd, xz, bzip2, 7z, and friends. Use when user mentions "tar", "gzip", "zip", "unzip", "compress", "extract", "archive", "bzip2", "xz", "zstd", "7z", "7zip", "rar", "pigz", "pbzip2", ".tar.gz", ".tgz", ".tar.xz", ".tar.zst", ".tar.bz2", "untar", "decompress", "incremental backup", "split archive", "parallel compression", "disk image", "dd", or working with compressed files. |
tar and compression
tar basics — create, extract, list
tar -cvf archive.tar dir/
tar -czvf archive.tar.gz dir/
tar -cjvf archive.tar.bz2 dir/
tar -cJvf archive.tar.xz dir/
tar --zstd -cvf archive.tar.zst dir/
tar -xvf archive.tar
tar -xzvf archive.tar.gz
tar -xjvf archive.tar.bz2
tar -xJvf archive.tar.xz
Modern tar auto-detects compression on extraction, so tar -xvf works for all formats.
tar flags reference
| Flag | Meaning |
|---|
-c | Create archive |
-x | Extract archive |
-t | List contents (don't extract) |
-r | Append files to existing archive (uncompressed .tar only) |
-u | Update — append only files newer than what's in archive |
-v | Verbose (show files) |
-f | Next argument is the filename — must come last before the filename |
-z | gzip compression |
-j | bzip2 compression |
-J | xz compression |
--zstd | zstd compression |
-C | Change to directory before operating |
-p | Preserve permissions |
-h | Follow symlinks (archive the target, not the link) |
-f must be the last flag before the archive name. tar -cfv archive.tar fails — tar looks for a file named v.
Append, update, exclude
tar -rvf archive.tar newfile.txt
tar -uvf archive.tar dir/
tar -czvf archive.tar.gz dir/ --exclude='*.log' --exclude='.git'
tar -czvf archive.tar.gz dir/ --exclude-vcs
tar -czvf archive.tar.gz dir/ --exclude-vcs-ignores
tar -czvf archive.tar.gz dir/ -X exclude.txt
Archive inspection and partial extraction
tar -tzvf archive.tar.gz
tar -tzvf archive.tar.gz | grep pattern
tar -tzvf archive.tar.gz --wildcards '*.conf'
tar -xzvf archive.tar.gz path/to/file.txt
tar -xzvf archive.tar.gz dir/subdir/
tar -xzvf archive.tar.gz --wildcards '*.conf'
tar -xzvf archive.tar.gz -C /target/dir/
tar -xzvf archive.tar.gz --strip-components=1
Preserving permissions, ownership, symlinks
tar -cpzvf archive.tar.gz --same-owner dir/
tar -chzvf archive.tar.gz dir/
tar -xpzvf archive.tar.gz --same-owner -C /restore/
tar -dvf archive.tar dir/
On macOS, --same-owner is default for root. On GNU/Linux, specify it explicitly.
Compression algorithms compared
| Tool | Flag | Ext | Speed | Ratio | Parallel tool |
|---|
| gzip | -z | .tar.gz | Fast | Good | pigz |
| bzip2 | -j | .tar.bz2 | Slow | Better | pbzip2 |
| xz | -J | .tar.xz | Very slow | Best | pxz / pixz |
| zstd | --zstd | .tar.zst | Very fast | Better | built-in -T |
| lz4 | --use-compress-program=lz4 | .tar.lz4 | Fastest | Lower | built-in |
Rough benchmarks (1 GB mixed data, single core):
| Tool | Compress | Decompress | Compressed size |
|---|
| lz4 | ~2s | ~0.5s | ~55% of original |
| zstd -1 | ~3s | ~1s | ~42% |
| gzip -6 | ~12s | ~3s | ~36% |
| zstd -19 | ~90s | ~1s | ~30% |
| xz -6 | ~120s | ~8s | ~28% |
Rule of thumb: quick backup → gzip/zstd. Source distribution → xz. General purpose → zstd. Real-time → lz4. bzip2 → legacy, skip it.
gzip / gunzip
gzip file.txt
gzip -k file.txt
gunzip file.txt.gz
gzip -9 file.txt
gzip -l file.txt.gz
zcat file.txt.gz
zstd (modern compression)
zstd file.txt
zstd -d file.txt.zst
zstd -19 file.txt
zstd --ultra -22 file.txt
zstd --fast file.txt
zstd -T0 file.txt
zstd --long file.txt
Dictionary compression (many small similar files)
zstd --train samples/* -o mydict.zst
zstd -D mydict.zst file.txt -o file.txt.zst
zstd -d -D mydict.zst file.txt.zst
Improves ratio 2-5x on small, structurally similar files (logs, JSON, configs).
Streaming
mysqldump mydb | zstd -T0 > dump.sql.zst
zstd -d < dump.sql.zst | mysql mydb
tar -cf - dir/ | pv | zstd -T0 > archive.tar.zst
Parallel compression (pigz, pbzip2, pxz)
tar -cf - dir/ | pigz -p 8 > archive.tar.gz
pigz -d archive.tar.gz
tar -cf - dir/ | pbzip2 -p8 > archive.tar.bz2
tar -cf - dir/ | pxz -T 8 > archive.tar.xz
tar -cf archive.tar.gz --use-compress-program='pigz -9' dir/
tar -xf archive.tar.gz --use-compress-program='pigz -d' -C /target/
zip / unzip
zip archive.zip file1 file2
zip -r archive.zip dir/
zip -r archive.zip dir/ -x '*.log'
unzip archive.zip
unzip archive.zip -d /target/dir/
unzip archive.zip file.txt
unzip -o archive.zip
unzip -l archive.zip
zipinfo archive.zip
zip -u archive.zip updated-file.txt
Password-protected zip
zip -e archive.zip file1 file2
unzip -P 'mypass' archive.zip
zip's encryption (ZipCrypto) is weak. Use 7z with AES-256 for real security.
Split zip archives
zip -r -s 100m archive.zip dir/
zip -s 0 archive.zip --out combined.zip
unzip combined.zip
7z operations (p7zip / 7-Zip)
7z a archive.7z dir/
7z a archive.7z dir/ -mx=9
7z a archive.7z dir/ -ms=on
7z a archive.7z dir/ -p'Pass' -mhe=on
7z a -v100m archive.7z dir/
7z x archive.7z
7z e archive.7z
7z x archive.7z -o/target/dir/
7z l archive.7z
7z t archive.7z
7z reads/writes: .7z, .zip, .tar, .gz, .bz2, .xz. Extracts .rar.
Piping tar over SSH
tar -czvf - dir/ | ssh user@host 'tar -xzvf - -C /target/'
ssh user@host 'tar -czvf - /remote/dir/' | tar -xzvf - -C /local/dir/
tar -cf - dir/ | zstd -T0 | ssh user@host 'zstd -d | tar -xf - -C /target/'
tar -cf - dir/ | pv -L 10m | ssh user@host 'tar -xf - -C /target/'
Incremental backups with tar
tar -czvf backup-full.tar.gz \
--listed-incremental=/var/backups/snapshot.snar dir/
tar -czvf backup-inc-$(date +%Y%m%d).tar.gz \
--listed-incremental=/var/backups/snapshot.snar dir/
tar -xzvf backup-full.tar.gz -C /restore/ --listed-incremental=/dev/null
tar -xzvf backup-inc-20260410.tar.gz -C /restore/ --listed-incremental=/dev/null
--listed-incremental=/dev/null during restore tells tar to extract everything. GNU tar only.
Split large archives
tar -czvf - dir/ | split -b 100m - archive.tar.gz.part-
cat archive.tar.gz.part-* | tar -xzvf -
Cross-platform: macOS vs GNU tar
| Feature | GNU tar (Linux) | BSD tar (macOS) |
|---|
--wildcards | Required for patterns | Default behavior |
--exclude-vcs-ignores | Supported | Not supported |
--zstd | Supported | Use --use-compress-program |
--listed-incremental | Supported | Not supported |
| Extended attributes | --xattrs | Stored by default |
brew install gnu-tar
tar -cf - dir/ | zstd > archive.tar.zst
COPYFILE_DISABLE=1 tar -czvf archive.tar.gz dir/
Compression for specific use cases
gzip -9 app.log
find /var/log -name '*.log' -mtime +7 -exec gzip {} \;
zstd --train logs/*.log -o log-dict.zst && zstd -D log-dict.zst -19 app.log
mysqldump mydb | zstd -T0 > mydb.sql.zst
pg_dump mydb | gzip -9 > mydb.sql.gz
pg_dump -Fc mydb > mydb.dump
tar -cJvf project.tar.xz --exclude-vcs project/
git archive --format=tar.gz HEAD > project.tar.gz
dd if=/dev/sda bs=4M status=progress | zstd -T0 > disk.img.zst
zstd -d < disk.img.zst | dd of=/dev/sda bs=4M status=progress
qemu-img convert -c -O qcow2 disk.raw disk.qcow2
Common patterns
tar -czvf "backup-$(date +%Y%m%d-%H%M%S).tar.gz" /path/to/dir/
tar -tzvf archive.tar.gz | head -20
tar -tzvf archive.tar.gz | sort -k3 -n -r | head -20
tar -czvf archive.tar.gz -T filelist.txt
find dir/ -size -10M | tar -czvf small-files.tar.gz -T -
gzip -t archive.tar.gz && echo "OK" || echo "CORRUPT"
xz -t archive.tar.xz
zstd -t archive.tar.zst