Search Inside Archives

Search the contents of compressed files and archives without extracting them to disk. The trick everywhere is the same: stream the file’s bytes to stdout, then pipe into grep.

Add -a to grep if it complains about binary input, and -i for case-insensitive.

Single compressed files (.gz, .bz2, .xz, .zst)

zgrep -i 'pattern' file.gz
bzgrep 'pattern' file.bz2
xzgrep 'pattern' file.xz
zstdgrep 'pattern' file.zst

Equivalent to zcat file.gz | grep 'pattern'. ripgrep does it too:

rg -z 'pattern' file.gz

tar.gz (and other compressed tarballs)

Stream every member to grep:

tar -xzOf archive.tar.gz | grep -a 'pattern'

-O writes extracted files to stdout. This loses which file matched. To keep the member name, loop over the listing:

tar -tzf archive.tar.gz | grep -v '/$' | while read -r f; do
  tar -xzOf archive.tar.gz "$f" | grep -aH --label="$f" 'pattern'
done

Slow on large archives, because each iteration re-reads the stream, but it shows member/path:matching line.

Limit to certain members:

tar -xzOf archive.tar.gz --wildcards '*.log' | grep -a 'pattern'

For a plain .tar, drop the z. For .tar.xz use -xJOf, for .tar.bz2 use -xjOf.

zip

zipgrep -i 'pattern' archive.zip             # prints member:matching line
zipgrep 'pattern' archive.zip '*.txt'        # only certain members
unzip -p archive.zip path/in/zip.txt | grep 'pattern'   # one member
unzip -p archive.zip | grep -a 'pattern'                 # all members

7z

7z x -so archive.7z path/in/archive.txt | grep 'pattern'   # one member
7z x -so archive.7z | grep -a 'pattern'                    # all members

One tool for most formats: ripgrep-all

rga wraps ripgrep with adapters that look inside zip, tar, gz, PDFs, Office documents and more, and reports which file inside matched:

rga 'pattern' archive.zip
rga -i 'pattern' /path/to/folder

Install: cargo install ripgrep_all or via your package manager. It needs ripgrep installed too.

Just search the file names inside an archive

tar -tzf archive.tar.gz | grep -i 'name'
unzip -l archive.zip | grep -i 'name'
7z l archive.7z | grep -i 'name'

See also