Home / Alt manpages / zdiff(1)

  • zdiff(1)
  • User command
  • linux

Compare Gzip Files Safely with zdiff and zcmp

You will compare compressed and uncompressed text without manually unpacking either file. Use zdiff when you want a readable line-by-line difference, or zcmp when you want the compact byte-comparison behaviour of cmp. Both commands leave their input files alone. This guide describes gzip 1.12, installed here as package version 1.12-1ubuntu3.2.

Allow about ten minutes. You need a shell, the gzip package, and read access to the files you are comparing. The examples are ordinary user commands. They do not need sudo.

1. Check the installed commands

Confirm which executables your shell will run and record the version before relying on behaviour in a script:

$ command -v zdiff zcmp gzip
/usr/bin/zdiff
/usr/bin/zcmp
/usr/bin/gzip
$ zdiff --version
zdiff (gzip) 1.12

The commands are supplied by gzip. The zdiff and zcmp manual pages have the same synopsis: options are passed to the underlying diff or cmp program. That means the output style belongs to those standard comparison tools, while gzip handles decompression first.

Checkpoint

If command -v finds nothing, stop and install the gzip package through your normal package-management process. Do not copy a replacement executable into a system directory.

2. Compare a compressed file with its plain peer

With one argument, the command expects a compressed file and compares it with the corresponding uncompressed file. For report.txt.gz, the implicit peer is report.txt:

$ zdiff /path/to/report.txt.gz
$ printf '%s\n' "$?"
0

No output means diff found no differences. The compressed file is read, its contents are compared with the plain peer, and neither input is modified. The same one-file form with zcmp compares the contents using cmp:

$ zcmp /path/to/report.txt.gz
$ printf '%s\n' "$?"
0

The direction matters for the filename convention. Running zdiff /path/to/report.txt does not automatically select report.txt.gz on this installed version. It reports an unknown compressed file extension because the argument itself is not a recognised compressed input. Pass the .gz path when using the one-file form.

3. Compare two files, including mixed compression

With two arguments, each input is decompressed if necessary before it is passed to the comparison program. This lets you compare a gzip archive with a plain working copy:

$ zdiff /path/to/old-report.txt.gz /path/to/new-report.txt
2c2
< beta
---
> gamma
$ printf '%s\n' "$?"
1

The exact line number and text depend on your files. The important result is status 1: diff found a difference. A status of 0 means the inputs compare equal. A status of 2 normally means a problem such as a missing file or an unreadable input, so do not treat every non-zero result as an ordinary content change.

Checkpoint

Test the status immediately after the comparison. Any command inserted between zdiff and printf replaces the status you are trying to inspect.

4. Choose readable output or a compact comparison

Use zdiff for reports, source files and configuration snapshots where changed lines need to be understood. It passes comparison options to diff, so a unified view is available:

$ zdiff -u /path/to/old-report.txt.gz /path/to/new-report.txt.gz
--- /dev/fd/...
+++ /dev/fd/...
@@ -1,2 +1,2 @@
 alpha
-beta
+gamma

The temporary-looking names in the headers are a known limitation of the wrapper: the manual warns that messages from diff or cmp can refer to names such as - instead of the paths you supplied. Read the hunks and exit status rather than building automation around those labels.

Use zcmp when you only need equal or different, or when the first differing byte is useful:

$ zcmp /path/to/old-report.txt.gz /path/to/new-report.txt.gz
/dev/fd/5 - differ: byte 7, line 2
$ printf '%s\n' "$?"
1

Options such as -l and -s belong to cmp, and options such as -u belong to diff. Check man cmp or man diff for the option you intend to pass. Do not assume an option is interpreted by gzip itself.

5. Put the result in a shell check

Keep the three useful outcomes distinct. This example prints a short message while preserving a failure caused by a missing or unreadable file:

if zdiff -q /path/to/old-report.txt.gz /path/to/new-report.txt.gz; then
    printf '%s\n' 'files are identical'
else
    status=$?
    case "$status" in
        1) printf '%s\n' 'files differ' ;;
        *) printf 'comparison failed with status %s\n' "$status" >&2; exit "$status" ;;
    esac
fi

Here -q is passed to diff and suppresses its normal difference report. If you need a report for a human, remove -q and keep the same status handling. The command still does not alter either input.

6. Diagnose failures without changing the files

First check that each named path exists and is readable:

$ ls -l /path/to/old-report.txt.gz /path/to/new-report.txt
$ test -r /path/to/old-report.txt.gz && echo 'old input readable'
$ test -r /path/to/new-report.txt && echo 'new input readable'

If the error mentions an unknown compressed file extension, check the argument rather than renaming files blindly. The wrapper recognises gzip input by its compressed filename extension. If a gzip file has a different name, give it a temporary name ending in .gz or decompress it through a separate, deliberate workflow. Renaming does not alter content, but it can confuse a batch job if the original name is part of its records.

Do not pipe comparison output into a command that hides the exit status unless you deliberately capture it. Also remember that gzip compression metadata is not the subject of this comparison: zdiff and zcmp compare the uncompressed contents. Two gzip files can have different headers or compression details and still compare equal here if their decompressed data is the same.

There is no destructive operation to undo. If a comparison fails, leave the inputs in place and correct the path, permissions or expected peer. Elevated privileges are not a normal fix; use them only under your organisation's access policy when the files genuinely require privileged reading.

Done means

  • zdiff gives a readable difference and zcmp gives compact comparison output when needed.
  • Compressed, plain and mixed input pairs have been compared without editing either file.
  • Status 0 means equal, status 1 means different, and other statuses are investigated as errors.
  • The one-file form is given the .gz path whose plain peer it should find.
  • Shell automation checks the exit status immediately and does not confuse a missing input with changed content.