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 (on a SunOS 5.10 )?

up vote 23 down vote accepted

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.

  • Where would the first option unzip the files to? – ziggy Aug 11 '11 at 12:02
  • 2
    unzip -c decompresses the file to stdout. It doesn't write the whole uncompressed file anywhere else. – Noah Aug 11 '11 at 12:40
  • oh ok thanks... – ziggy Aug 11 '11 at 13:34
  • +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. – Mike Aug 3 '14 at 7:38
  • 2
    My version of unzip uses -p for streaming to pipe! – gavenkoa Mar 23 '16 at 18:19

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
    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 '15 at 13:04

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

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.