42

I am working on SunOS 5.10. I have a folder that contains about 200 zip files. Each zip file contains only one text file in it. I would like to search for a specific string in all the text files in all the zip files.

I tried this (which searches for any text file in the zip file that contains the string "ORA-") but it didn't work.

zipgrep ORA-1680 *.zip

What is the correct of doing it without uncompressing the zip files?

1

4 Answers 4

39

It is in general not possible to search for content within a compressed file without uncompressing it one way or another. Since zipgrep is only a shellscript, wrapping unzip and egrep itself, you might just as well do it manually:

for file in *.zip; do unzip -c "$file" | grep "ORA-1680"; done

If you need just the list of matching zip files, you can use something like:

for file in *.zip; do
    if ( unzip -c "$file" | grep -q "ORA-1680"); then
        echo "$file"
    fi
done

This way you are only decompressing to stdout (ie. to memory) instead of decompressing the files to disk. You can of course try to just grep -a the zip files but depending on the content of the file and your pattern, you might get false positives and/or false negatives.

5
  • Where would the first option unzip the files to?
    – ziggy
    Aug 11, 2011 at 12:02
  • 2
    unzip -c decompresses the file to stdout. It doesn't write the whole uncompressed file anywhere else.
    – Noah
    Aug 11, 2011 at 12:40
  • +1 tks a lot it save my day . I juste add echo "$file"; unzip -c "$file" | grep -q "ORA-1680"; to know the file name + the result. Aug 3, 2014 at 7:38
  • 2
    My version of unzip uses -p for streaming to pipe!
    – gavenkoa
    Mar 23, 2016 at 18:19
  • This works where all the single line commands returned "standard output", not a file name +1
    – alimack
    Jun 15, 2017 at 16:40
26

zipgrep takes a single file. To make it work across multiple files put it in a loop:

for i in *.zip
do
   zipgrep ORA-1680 "$i"
done
1
  • 3
    In one line that also print zip filename if there is a match: for i in *.zip; do zipgrep TextToSearch $i && echo $i; done
    – baptx
    Mar 2, 2015 at 13:04
4

The AVFS filesystem presents a view of the filesystem where every archive file /path/to/foo.zip is accessible as a directory ~/.avfs/path/to/foo.zip#. It's a FUSE filesystem, which you can install on Solaris. AVFS provides read-only access to most common archive file formats.

mountavfs
for z in ~/.avfs$PWD/*.zip; do
  find "$z#" -exec grep ORA-1680 {} +
done
fusermount -u ~/.avfs   # optional
4

Try ugrep

ugrep recursively searches zip, gz, tar, tgz, bz2, lz4, zstd, pax, cpio, and other types of compressed files and archives with option -z.

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .