Question: I'm trying to find out what modules [`use Test::Version`](http://search.cpan.org/dist/Test-Version/lib/Version.pm) in cpan. So I've used [`minicpan`](http://search.cpan.org/dist/CPAN-Mini/bin/minicpan) to mirror it. My problem is that I need to iterate through the archives that are downloaded, and grep the files that are in the archives. Can anyone tell me how I might do this? preferably in a way that tells me which file in the archive and what line it's on.

*(note: they aren't all tarballs some are zip files)*

Answer: 
[ugrep](https://github.com/Genivia/ugrep) recursively searches compressed files (gz/Z/bz2/lzma/xz/lz4/zstd) and archives (cpio/tar/pax/zip) with option `-z`. Options `-z --zmax=2` searches compressed files and archives embedded within compressed files and archives (hence zmax=2 levels).
Maybe my answer will helpfull for someone:

```
#!/bin/bash

findpath=$(echo $1 | sed -r 's|(.*[^/]$)|\1/|')

# tarballs to check in
find $findpath -type f | while read tarball; do

    # get list of files in tarball (not dirs ending in /):
    if [ -n "$(file --mime-type $tarball | grep -e "application/jar")" ]; then

        jar tf $tarball | grep -v '/$' | while read file; do
            # get contents of file and look for string
            grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")

            if [ -n "$grepout" ]; then
                echo "*** $tarball has matching file ($file):"
                echo $grepout
            fi

        done

    elif tar -tf $tarball 2>/dev/null; then

        tar -tf $tarball | grep -v '/$' | while read file; do
            # get contents of file and look for string
            grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")

            if [ -n "$grepout" ]; then
                echo "*** $tarball has matching file ($file):"
                echo $grepout
            fi

        done

    else
        file=""
        grepout=$(grep $3 -e "$2" $tarball)

        if [ -n "$grepout" ]; then
            echo "*** $tarball has matching:"
            echo $grepout
        fi

    fi

done

```