How to Extract tar.gz and .gz Files in Linux

Deepak Prasad
Tested on Red Hat Enterprise Linux 10.2 (lab VM)
Package tar (GNU tar) 1.35
gzip 1.13
Applies to RHEL, Rocky Linux, AlmaLinux, CentOS Stream, Fedora, Debian, Ubuntu, and other GNU/Linux systems with GNU tar and gzip
Privilege Normal user (read archives you can open; write where you have permission)
Scope Full extraction of .tar.gz and .tgz archives; decompress plain .gz files; list archive members; extract to another directory; view gzip streams without writing files. Does not cover selective file extraction or recursive bulk unpacking.
Related guides tar command
Extract specific files from tar.gz
tar --strip-components
Linux file management
gzip command

A .tar.gz file is a tar archive wrapped in gzip compression. A plain .gz file is usually one compressed file, not an archive at all. Mixing the two leads to the wrong command and confusing errors, so this guide keeps them separate from the first section onward.

You will see .tar.gz on source tarballs, container image layers, and backup bundles that must preserve paths and permissions. You will see plain .gz on rotated logs, single-file exports, and gzip-compressed payloads that are not tar archives at all.


Quick Reference: tar.gz vs .gz

File type What it contains Tool Typical extract command
.tar.gz / .tgz Many files and directories in a tar archive, gzip-compressed GNU tar tar -xf archive.tar.gz
.gz One gzip-compressed stream (often a single file) gunzip / gzip -d gunzip file.gz

GNU tar 1.35 on current GNU/Linux can read .tar.gz with tar -xf alone and detect gzip automatically. tar -xzf remains valid when you want to name the compression filter explicitly.


Difference Between .gz, .tar.gz, and .tgz

Gzip compresses a single byte stream. When you gzip one file, you get document.pdf.gz. When you gzip a tar archive that already bundles many paths, you get release.tar.gz.

Extension Structure Opens with
.gz One compressed stream gunzip, gzip -d, zcat
.tar.gz tar archive + gzip wrapper tar -xf (GNU tar auto-detects gzip)
.tgz Same as .tar.gz tar -xf

Both .tar.gz and plain .gz files can be identified as gzip-compressed data by file. That output alone does not prove the payload is a tar archive.

Do not run tar -xf on a plain .gz log or config backup and expect a folder tree. Use gunzip, gzip -d, or zcat for known single-file gzip payloads.

If you need one member from a .tar.gz without unpacking everything, list members with tar -tf and pass the exact stored path to tar -xf for a partial extract.


Prepare lab archives

The examples below use a disposable directory under /tmp/tar-gz-lab. Create the sample tree and archives once:

bash
mkdir -p /tmp/tar-gz-lab/demo

Add two demo files the archive will bundle:

bash
printf 'hello from demo\n' > /tmp/tar-gz-lab/demo/readme.txt

Add a second config file:

bash
printf 'config line\n' > /tmp/tar-gz-lab/demo/app.conf

Pack the demo/ directory into release.tar.gz:

bash
tar -czf /tmp/tar-gz-lab/release.tar.gz -C /tmp/tar-gz-lab demo/

Copy the same archive as bundle.tgz for the .tgz example later:

bash
cp /tmp/tar-gz-lab/release.tar.gz /tmp/tar-gz-lab/bundle.tgz

Build a plain .gz file for the type-check examples later in this guide:

bash
printf 'hello\n' | gzip -c > /tmp/tar-gz-lab/plain.gz

Create stream.txt.gz for the read-only gzip examples:

bash
printf 'stream read\n' | gzip -c > /tmp/tar-gz-lab/stream.txt.gz

Confirm a gzip file contains a tar archive

Run file when you only know the download is gzip-compressed:

bash
file /tmp/tar-gz-lab/plain.gz /tmp/tar-gz-lab/release.tar.gz

Sample output:

output
/tmp/tar-gz-lab/plain.gz:       gzip compressed data, from Unix, original size modulo 2^32 6
/tmp/tar-gz-lab/release.tar.gz: gzip compressed data, from Unix, original size modulo 2^32 10240

Both lines say gzip compressed data, so file cannot choose between tar and non-tar payloads. List members with tar -tf when you expect a directory tree:

bash
tar -tf /tmp/tar-gz-lab/release.tar.gz

Sample output:

output
demo/
demo/readme.txt
demo/app.conf

On a valid tar archive, tar prints member paths. Test a known plain .gz the same way:

bash
tar -tf /tmp/tar-gz-lab/plain.gz

GNU tar does not list any members because the decompressed payload is not tar data. Depending on version and warning settings, tar may report an archive-format problem (for example Terminating zero blocks missing at 0) or exit without listing paths. Either outcome means you should use gunzip, gzip -d, or zcat instead of tar.


When you still see tar -xzf

Scripts and older tutorials spell out tar -xzf because -z means “filter through gzip.” On current GNU tar, both forms unpack the same .tar.gz archive:

Form Meaning on GNU tar 1.35
tar -xf archive.tar.gz Auto-detect gzip while reading
tar -xzf archive.tar.gz Explicitly pipe through gzip

On current GNU tar, tar -xf archive.tar.gz automatically detects gzip compression. tar -xzf remains valid and is still useful in scripts where you want to state the compression method explicitly or where portability to non-GNU tar implementations matters.


Extract a .tar.gz File with tar

Use the release.tar.gz archive from Prepare lab archives. Change into the lab directory:

bash
cd /tmp/tar-gz-lab

Extract every member into the current working directory:

bash
tar -xf release.tar.gz

GNU tar prints nothing on success when you omit -v. List what landed:

bash
find demo -type f

Sample output:

output
demo/readme.txt
demo/app.conf

The long form tar -xzf release.tar.gz still works. The -z flag tells GNU tar to pipe through gzip explicitly. On GNU tar 1.35, tar -xf alone auto-detects gzip for .tar.gz archives.

Add -v when you want tar to print each path as it extracts:

bash
tar -xvf release.tar.gz

Sample output:

output
demo/
demo/readme.txt
demo/app.conf

For more flags and archive creation examples, run tar --help or read man tar.

Tar preserves the paths, timestamps, and permission bits stored in the archive header. If extracted files look executable when you did not expect that, check what the packager stored with tar -tvf before you run anything from the unpack directory.


Extract .tar.gz to Another Directory

By default, tar recreates the stored directory tree under your current path. Create the destination directory first:

bash
mkdir -p /tmp/tar-gz-lab/extracted

Point tar at that folder with -C before it writes any members:

bash
tar -xf release.tar.gz -C /tmp/tar-gz-lab/extracted

Tar places the demo/ directory from the archive under extracted/. Confirm with:

bash
ls /tmp/tar-gz-lab/extracted/demo/

Sample output:

output
app.conf
readme.txt

The -C directory must exist before you run tar. Tar does not create missing parent paths for you.

You can place -C before or after the archive name on GNU tar as long as the next argument is the destination path. This equivalent form names the destination first:

bash
tar -C /tmp/tar-gz-lab/extracted -xf release.tar.gz

Both -C placements leave the same tree under extracted/demo/.


List .tar.gz Contents Without Extracting

Before you unpack a large download, list members with -t and skip extraction:

bash
tar -tf release.tar.gz

Sample output:

output
demo/
demo/readme.txt
demo/app.conf

Add -v for permission, owner, and size columns (tar -tvf). The paths tar prints are the exact strings you need when extracting individual members from a partial unpack.

Listing is cheap compared to writing thousands of small files to disk. On a server with limited free space, run tar -tf first to confirm the archive contains what you expect before you extract.


Extract a .tgz Archive

A .tgz file is a gzip-compressed tar archive, identical to .tar.gz. Only the filename extension differs. Software vendors use .tgz when they want a shorter name; the commands are the same.

Prepare an output directory:

bash
mkdir -p /tmp/tar-gz-lab/tgz-out

Run the same extract command you would use for .tar.gz:

bash
tar -xf bundle.tgz -C /tmp/tar-gz-lab/tgz-out

List the result:

bash
ls -R /tmp/tar-gz-lab/tgz-out

Sample output:

output
/tmp/tar-gz-lab/tgz-out:
demo

/tmp/tar-gz-lab/tgz-out/demo:
app.conf
readme.txt

Decompress a Plain .gz File with gunzip

Plain .gz files need gunzip or gzip -d, not tar. The command replaces file.gz with the decompressed file by default.

Build a small example archive to decompress:

bash
printf 'plain gzip test\n' | gzip -c > /tmp/tar-gz-lab/notes.txt.gz

Run gunzip on the compressed file:

bash
gunzip /tmp/tar-gz-lab/notes.txt.gz

gunzip removes the .gz file after a successful run. Read the result:

bash
cat /tmp/tar-gz-lab/notes.txt

Sample output:

output
plain gzip test

gzip -d is equivalent to gunzip. By default, decompression replaces the .gz file with the decompressed file, normally removing the recognized gzip suffix from the filename. For notes.txt.gz, that writes /tmp/tar-gz-lab/notes.txt.

If you batch-decompress many .gz files in one directory, gunzip *.gz expands each match in turn. That is separate from unpacking a .tar.gz, which is still a single tar operation on one archive file.


Keep the Original .gz File After Decompression

By default, gunzip deletes the compressed file. Pass -k (keep) to leave the .gz in place.

Create and compress a file:

bash
printf 'keep me\n' > /tmp/tar-gz-lab/keep.txt

The -n flag on gzip skips storing the original filename in the header, which keeps tiny test files predictable:

bash
gzip -n /tmp/tar-gz-lab/keep.txt

Decompress while keeping the .gz copy:

bash
gunzip -k /tmp/tar-gz-lab/keep.txt.gz

Both files should exist now:

bash
ls -l /tmp/tar-gz-lab/keep.txt*

Sample output:

output
-rw-r--r--. 1 root root  8 Aug 15 18:05 /tmp/tar-gz-lab/keep.txt
-rw-r--r--. 1 root root 28 Aug 15 18:05 /tmp/tar-gz-lab/keep.txt.gz

Read a .gz File Without Extracting It

When you only need to peek at compressed text, stream it to stdout instead of writing a new file on disk.

zcat (or gzip -dc) prints the decompressed bytes to the terminal:

bash
zcat /tmp/tar-gz-lab/stream.txt.gz

Sample output:

output
stream read

gzip -l shows compressed size, uncompressed size, and ratio without decompressing to a separate file:

bash
gzip -l /tmp/tar-gz-lab/stream.txt.gz

Sample output:

output
compressed        uncompressed  ratio uncompressed_name
                 30                  12   0.0% stream.txt

For long logs, pipe to less: zcat big.log.gz | less.

gunzip -c behaves like zcat and is handy in scripts when you want stdout without touching the .gz file on disk:

bash
gunzip -c /tmp/tar-gz-lab/stream.txt.gz | wc -l

Sample output:

output
1

One line means the compressed file held a single line of text after decompression.


Common tar.gz and gunzip Errors

Symptom Likely cause Fix
tar: archive.tar.gz: Cannot open: No such file or directory Wrong path or typo Run ls on the archive path; use tab completion
gzip: file.gz: No such file or directory Missing .gz file Confirm the filename with ls *.gz
gzip: file.txt already exists; not overwritten Decompressed file already present Remove or rename the existing file, or use gunzip -f to force
tar -tf lists no members on a .gz file Payload is plain gzip, not tar Use gunzip, gzip -d, or zcat instead of tar
tar: Unexpected EOF in archive Truncated or corrupt download Re-download; verify checksum if provided

Missing archive paths fail fast:

bash
tar -xf /tmp/tar-gz-lab/missing.tar.gz

Sample output:

output
tar: /tmp/tar-gz-lab/missing.tar.gz: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

When gunzip refuses to overwrite an existing file, either remove the target or pass -f. The collision happens when the decompressed filename already exists on disk:

bash
printf 'y\n' > /tmp/tar-gz-lab/dup.txt

Compress it so only dup.txt.gz remains:

bash
gzip -n /tmp/tar-gz-lab/dup.txt

Recreate the plaintext file so gunzip has something to collide with:

bash
printf 'y\n' > /tmp/tar-gz-lab/dup.txt

Try decompression without -f:

bash
gunzip /tmp/tar-gz-lab/dup.txt.gz

Sample output:

output
gzip: /tmp/tar-gz-lab/dup.txt already exists;	not overwritten

gunzip -f forces overwrite when you are sure the existing file is safe to replace.


References


Summary

A .tar.gz or .tgz file is a tar archive inside gzip compression. On GNU tar, extract the whole archive with tar -xf archive.tar.gz; current GNU tar detects gzip without -z, though tar -xzf still works when you want the filter named explicitly or need compatibility with non-GNU tar. Use -C /destination when you want the tree somewhere other than the current directory, and tar -tf when you only need a member list before unpacking.

A plain .gz file is different: it wraps one compressed stream, so reach for gunzip or gzip -d instead of tar. Add gunzip -k when you want to keep the .gz after decompression, and use zcat or gzip -l to read or inspect compressed data without writing a new file.

When you need a single file or subdirectory from a .tar.gz, extract only those members instead of unpacking the full archive and deleting what you do not need.

On shared servers, extract as a normal user into a directory you own (for example ~/downloads/ or /tmp/$USER/). You only need root when the destination path or extracted permissions require elevated access. Check ownership and permission bits after you unpack third-party tarballs.


Frequently Asked Questions

1. Do I need the -z flag to extract a tar.gz file?

On GNU tar 1.35, tar -xf archive.tar.gz auto-detects gzip. tar -xzf remains valid when you want to name the gzip filter explicitly or when scripts must run on non-GNU tar implementations.

2. Can I use tar to decompress a plain .gz file?

No. A plain .gz file is one gzip-compressed stream, not a tar archive. Use gunzip, gzip -d, or zcat. Tar is for archives such as .tar.gz and .tgz.

3. What is the difference between tar.gz and tgz?

They are the same format. .tgz is a short filename extension for a tar archive compressed with gzip.

4. How do I extract only one file from a tar.gz?

List members with tar -tf, then pass the exact stored path to tar -xf. See the dedicated guide on extracting specific files from tar.gz for wildcards, directories, and strip-components.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration