The GNU and BSD tar
commands don't support that as far as I know, but:
If the tar
archive is small enough or not read from a medium that's expensive to rewind (actual tape archives), you could list_of_matching_files=$(tar -tf file.tar.gz | grep '(aaa|bbb|ccc)')
to compile a list of files. You will not like what happens when file names contain line breaks, which is perfectly legal.
So, that would leave you (at least in GNU tar
) with the option to execute a command on each executed file, using the --to-command=
option. tar
will set the TAR_REALNAME
environment variable, which your program can use to select whether the data piped in will be written to a file of an appropriate name, or just ignored. You should then also handle the other TAR_**
environment variables set to handle file/directory types, owners, modes and dates correctly. In short, aside from reading the (pretty stupid) .tar
format, you'd be doing tar
's job in a program / shell script of your own.
Alternatively, honestly, since a tar needs to be read sequentially anyways, and storage is usually cheap, just extract everything, noting the extracted files on the way, and delete the "wrong" ones later.
Even more alternatively, might be worth trying whether 7z
extracting a tar file also aborts when a pattern doesn't match.
And, finally: Every proper programming language probably has a tar
-consuming library. Might really be worth the six-ish lines of Python, see the second example from the official documentation:
#!/usr/bin/env python3
import os
import tarfile
def py_files(members):
for tarinfo in members:
"""
modify this check: only `yield tarinfo` if the
tarinfo.name matches your needs. Conveniently,
python has string functions like `tarinfo.name.startswith("foo")`
and a capable regex library
"""
if os.path.splitext(tarinfo.name)[1] == ".py":
yield tarinfo
tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()