Do you know a GNU/Linux tool that can search for a file inside archive file (zip, tar, etc) nested in another archive file (also zip, tar, etc)?
It would be sufficient to search only by file name. I'm interested in Free/Open Source software.
Do you know a GNU/Linux tool that can search for a file inside archive file (zip, tar, etc) nested in another archive file (also zip, tar, etc)?
It would be sufficient to search only by file name. I'm interested in Free/Open Source software.
You can use the AVFS filesystem to access any archive as if it was a directory. (There are multiple ways to do this, AVFS has the advantage that you don't need to mount every archive explicitly.) Install it (preferably from your distribution, if it has this package), and run the command mountavfs
. This creates a view of the filesystem at ~/.avfs
. In this view, whenever ~/.avfs/path/to/foo.zip
is an archive file (all common archive types are supported), an additional directory ~/.avfs/path/to/foo.zip#
contains the content of the archive. This works recursively: if foo.zip
itself contains archives, you can access their contents with a path like ~/.avfs/path/to/foo.zip#/subdir/bar.tar.gz#myfile
.
Now that the job has been reduced to exploring a directory tree, you can write a small shell script that leverages the find
command to search within nested archives. Here's a recursive script that takes two arguments, a directory or archive to explore and a file name wildcard pattern to search for.
#!/bin/sh
# Use the AVFS view, to search inside archives
mountavfs
case "$1" in
~/.avfs/*) root="$1";;
/*) root="$HOME/.avfs$1";;
*) root="$HOME/.avfs$PWD/$1";;
esac
# If there is a ...# directory, assume this is an archive with its companion
# artificial directory
if [ -e "$root#/" ]; then root="$root#/"; fi
# Print matches, and search recursively inside archives
find "$root" -name "$2" -print -o \
\( -name '*.zip' -o -name '*.tgz' -o -name '*.tar.gz' -o -name '*.tar.bz2' -o -name '*.tar.xz' \) \
-exec "$0" {} "$2" \;
Cross-platform solution written in Go with Apache 2 License: ztgrep
It does not write to disk, and it can search multiple archives concurrently.
Use -b
to skip searching file contents.
Disclosure: I am the maintainer of this tool