There’s one command that trips up half the internet: tar. Not because it’s hard—it’s simple—but because the flag mnemonic is so overused that everyone’s confused about what it actually means.
Here’s the thing: you don’t need to memorize every variation. Once you understand the create / extract / list pattern and the compression flags, you’re golden. Let me break it down before you go cargo-culting xvzf into your deploy scripts.
The Core Flags: Extract vs Create vs List
Tar has three main modes. Pick one:
- x = extract (unpack)
- c = create (pack into tarball)
- t = list (show contents without extracting)
Then add compression flags and modifiers:
- z = gzip compression (.tar.gz, .tgz)
- j = bzip2 compression (.tar.bz2)
- J = xz compression (.tar.xz)
- v = verbose (show file names as they extract)
- f = file (the next argument is the filename)
That’s it. Everything else is built from these.
The Classic Example (And Why It Works)
tar xvzf archive.tar.gzReading left to right:
- x = extract
- v = verbose output
- z = gzip decompression
- f = next arg is the filename
The mnemonic that haunts everyone: “extract verbosely from gzip file”. The internet calls it xvzf, so people just copy-paste it. But you can rearrange these flags—tar fxvz archive.tar.gz works too, as long as f is last (or the filename immediately follows).
Modern tar is smart: tar xf archive.tar.gz auto-detects the compression. You often don’t need the z flag anymore.
Compression Formats: tar.gz vs tar.bz2 vs tar.xz
Each format trades off speed vs compression ratio:
| Format | Size | Speed | Command |
|---|---|---|---|
| .tar.gz | Medium | Fast | tar xvzf file.tar.gz |
| .tar.bz2 | Small | Slow | tar xvjf file.tar.bz2 |
| .tar.xz | Smallest | Slowest | tar xvJf file.tar.xz |
Gzip (z): Default. Balances speed and compression. Most common on the internet.
Bzip2 (j): Smaller files, slower to compress/extract. Used in old RedHat/CentOS repos.
XZ (J): Best compression, slowest. Modern standard for kernel downloads and Linux distributions.
# Extract any of these (modern tar detects compression)tar xf archive.tar.gztar xf archive.tar.bz2tar xf archive.tar.xz
# Or be explicittar xzf archive.tar.gz # gziptar xjf archive.tar.bz2 # bzip2tar xJf archive.tar.xz # xz (capital J)Extract to a Specific Directory
Don’t clutter your current directory. Use -C to extract into a target:
tar xvzf archive.tar.gz -C /target/directoryThis extracts everything inside /target/directory. The directory must exist, or you’ll get an error. If you need to create it first:
mkdir -p /target/directory && tar xvzf archive.tar.gz -C /target/directoryWhy -C matters: Many tarballs come with a top-level directory (archive/file1, archive/file2). Without -C, they dump into your current dir. With -C, they nest properly. Always check first.
List Contents Without Extracting
See what’s in a tarball before you extract:
# List all filestar tvzf archive.tar.gz
# Just file names (no details)tar tzf archive.tar.gz
# Count filestar tzf archive.tar.gz | wc -l
# Find a specific filetar tzf archive.tar.gz | grep "config"The t flag (list) is your friend when you’re skeptical about what you’re extracting.
Create a Tarball
Package your own files:
# Create tar.gz from a directorytar czf archive.tar.gz /path/to/directory/
# Create tar.bz2tar cjf archive.tar.bz2 /path/to/directory/
# Create tar.xztar cJf archive.tar.xz /path/to/directory/Exclude Files During Creation (or Extraction)
Don’t pack everything:
# Exclude node_modules and .git when creatingtar czf project.tar.gz /path/to/project \ --exclude=node_modules \ --exclude=.git \ --exclude=.DS_StoreFor extraction (rare), exclude during unpacking:
tar xzf archive.tar.gz --exclude="*/tests/*"Extract a Single File
Pull one file from the tarball without extracting the whole thing:
tar xvzf archive.tar.gz path/to/file.txtThis extracts only path/to/file.txt and recreates the directory structure. Useful for grabbing a config file from a backup.
Gotchas That Bite You
1. Leading ./ Gets Stripped
When you create a tarball with tar czf archive.tar.gz ./mydir, tar stores it as mydir/file, not ./mydir/file. When someone extracts, the leading ./ doesn’t exist. Not a problem 99% of the time, but if you’re distributing software, be aware.
2. Absolute Paths Become Relative
If you pack /etc/config.txt, tar strips the leading / and stores it as etc/config.txt. This is a safety feature—extracting a tar that has absolute paths would overwrite your system files. Always use relative paths when creating:
# Goodtar czf backup.tar.gz -C /etc config.txt
# Risky (but tar will warn you)tar czf backup.tar.gz /etc/config.txt3. Permission Hell
Tarballs preserve file permissions. If you extract a tarball as root, the files stay owned by whatever UID was in the tarball (often a random number from another system). Use --no-same-owner if you’re deploying:
tar xzf archive.tar.gz --no-same-ownerOne-Liners That Save Time
# Extract and see what's extractingtar xvzf archive.tar.gz | head -20
# Find the biggest file in a tarballtar tzf archive.tar.gz | xargs -I {} tar xzOf archive.tar.gz {} | wc -c | sort -rn | head -1
# Extract to RAM (dangerous, but fast)tar xzOf archive.tar.gz | tar x -C /tmp
# Count total size before extractingtar tzf archive.tar.gz | xargs du -ch | tail -1The Cheat Sheet
| Task | Command |
|---|---|
| Extract tar.gz | tar xf file.tar.gz |
| Extract tar.bz2 | tar xf file.tar.bz2 |
| Extract tar.xz | tar xf file.tar.xz |
| List contents | tar tf file.tar.gz |
| Create tar.gz | tar czf archive.tar.gz /path/ |
| Extract to dir | tar xf file.tar.gz -C /target |
| Extract one file | tar xf file.tar.gz path/to/file |
| Exclude on create | tar czf archive.tar.gz --exclude=dir /path/ |
Forget the mnemonics. Just remember: x to extract, c to create, t to list. Add your compression letter and f, and you’re done. Stop overthinking it.