Home / Alt manpages / ptargrep(1)

  • ptargrep(1)
  • User command
  • linux

Find Matching Files Inside a tar Archive with ptargrep

By the end of this guide, you will be able to search the contents of a tar archive, list the files containing a match, and extract only those files into a controlled directory. The commands use the ptargrep supplied with Perl 5.38.2 on the system used for this guide. Allow about ten minutes, plus time to inspect the archive before extracting anything.

Before you start

You need a Linux shell, the perl package, and a tar archive you are allowed to inspect. No command in this guide needs elevated privileges. Use a working directory where creating files is harmless.

Set the archive path to your own file. Quoting the variable matters when a path contains spaces:

archive='/path/to/config-backup.tar'
test -r "$archive" && command -v ptargrep

Expected output is the path to ptargrep, such as /usr/bin/ptargrep. If the first command fails, correct the path or permissions before continuing.

Checkpoint 1: list matches without extracting

Start with --list-only. It prints the pathname of every archive member whose contents contain a matching line. This is the safest first pass because it does not create files:

ptargrep --list-only 'Host' "$archive"

A configuration archive might produce output like this:

/etc/sshd_config

The pattern is a Perl regular expression, not merely a literal text search. In this example, Host matches that capitalisation. A pattern matches a file if at least one line in the file matches; the command prints the filename, not the matching line.

Checkpoint 2: make the search case-insensitive

Add --ignore-case, or its short form -i, when the capitalisation is not useful:

ptargrep --list-only --ignore-case 'host' "$archive"

This can find both Host and host. To use regular-expression features, quote the pattern so the shell does not interpret its punctuation:

ptargrep --list-only -i '^(host|hostname)[[:space:]]' "$archive"

Use a narrow expression when a broad word search would return too many files. If a pattern comes from another person or a script, review it first: regular expressions can be surprising, and an invalid expression will stop the search.

Checkpoint 3: extract matches into a disposable directory

Without --list-only, the default action is to extract every matching file. Change into a new directory before doing that:

mkdir -p ./ptargrep-review
cd ./ptargrep-review
ptargrep 'Host' "$archive"
find . -type f -print

With an archive member named etc/sshd_config, the final command should show:

./etc/sshd_config

Directory paths are retained by default. This keeps similarly named files apart and makes the extracted copy easier to relate to the archive. The extraction happens in the directory from which you run ptargrep, so check pwd first if the destination matters.

Treat an archive from an untrusted source as untrusted input. List its matches first, extract into an empty review directory, and inspect the result before opening or running anything from it. Do not extract over a working tree or a directory containing valuable files.

Flatten paths only when you have checked for collisions

The --basename option, or -b, discards archive directories during extraction:

mkdir -p ./ptargrep-flat
cd ./ptargrep-flat
ptargrep --basename 'Host' "$archive"
find . -maxdepth 1 -type f -print

A member such as etc/sshd_config becomes ./sshd_config. This is convenient for a small, known archive, but it changes the safety boundary: if two matching members have the same basename, the later extraction overwrites the earlier one. Recovery is to remove the review directory and repeat the extraction without --basename, provided you have no other work in that directory:

rm -rf -- ./ptargrep-flat

The removal above is irreversible for files created there, so confirm the path with pwd and find ./ptargrep-flat -maxdepth 2 -type f before using it. If the directory contains anything else, move the files you need elsewhere and remove only the generated files.

Search more than one archive

Pass multiple tar filenames after the pattern. Each archive is processed in turn:

ptargrep --list-only -i 'password|token' \
  '/path/to/backup-2026-01.tar' \
  '/path/to/backup-2026-02.tar'

This reports matching archive paths to standard output. The output does not add an archive label, so search one archive at a time when you need an unambiguous audit record, or record the command and its input filenames alongside the output.

Common traps

  • Unexpected extraction: omitting --list-only extracts matches by default. Make listing your first command.
  • Missing lowercase matches: matching is case-sensitive unless --ignore-case is present.
  • Wrong destination: extraction uses the current directory, not the directory containing the archive. Verify it with pwd.
  • Overwritten basenames: --basename can replace an earlier match with the same filename. Keep archive paths unless flattening is necessary.
  • Regex errors: patterns use Perl regular-expression syntax. Quote shell metacharacters and test a small expression with --list-only first.
  • Confusing output: matching prints filenames, not matching lines. Extract a selected file or use a separate tool on the extracted copy when you need the lines themselves.

Done means

  • ptargrep --list-only produced the expected matching archive paths.
  • You chose case-sensitive or case-insensitive matching deliberately.
  • Any extraction happened in a disposable, verified directory.
  • You retained archive paths unless you had checked for basename collisions.
  • You can reproduce the search from the recorded pattern, archive path and options.