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.
The route
Jump straight to the step you need, or tick off Done means at the end.
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-onlyextracts matches by default. Make listing your first command. - Missing lowercase matches: matching is case-sensitive unless
--ignore-caseis present. - Wrong destination: extraction uses the current directory, not the directory containing the archive. Verify it with
pwd. - Overwritten basenames:
--basenamecan 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-onlyfirst. - 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-onlyproduced 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.