Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Given a set of zip files, is there an easy way to list only those zipfiles that contain files whose names match a given pattern, cf. using grep -l to list only files whose contents contain lines matching a given pattern?

The best I've been able to come up with is

for i in $ZIPFILE_LIST
> do j=$(basename $i)
> unzip -l $i > /tmp/$j
> grep -l $PATTERN /tmp/$j
> rm /tmp/$j
> done

but it's fairly hacky and without e.g. passing the grep output through sed (with various escaping headaches) it's going to tell you which files you care about, but it's not actually going to give you the full paths in a form you can then pass on to something else. It seems like this is a reasonably common use case and there ought to be some better out-of-the-box tool or combination of tools to do it.

share|improve this question

4 Answers 4

unzip -l files.zip | grep filename
share|improve this answer
    
Yes, that's pretty much what I said in the question. –  David Moles Jun 2 at 16:49

I think you want zipgrep, which is installed in stock Ubuntu (so maybe installed on your system). It's a shell script that uses unzip and egrep internally.

share|improve this answer
    
See comments on Iain's answer -- I'm not looking for matching files, I'm looking for matching filenames. –  David Moles May 30 at 22:58
    
Have you tried zipgrep -l? It works for me. Sorry if I didn't spell it out. –  Chris Lear May 31 at 8:16
    
I realise that this doesn't match your description ("contain files whose names match a given pattern"), but I think it matches your code, and your grep -l example. –  Chris Lear May 31 at 8:17
    
It doesn't, because I'm not unzipping the zipfiles, I'm just listing their contents (unzip -l). –  David Moles Jun 2 at 16:50

You can use the potent find command for that purpose, like so: find <location> -regex '<your regex here>. Please note that the regex is matched against the whole output, i.e. the full path, not just the filename -- which seems to be just what you want but may cause confusion at first and you may want to start your regex with ^.* to match anything in the middle of the filename or path.

share|improve this answer
1  
Find is not quite potent enough to look inside zipfiles like the OP is asking for. –  Ladadadada May 31 at 6:54

Would the Python zipfile module help solve your problem?

eg:

import zipfile

def findfileinzip(source_filename, pattern):
    print(pattern)
    zf = zipfile.ZipFile(source_filename,'r')
    for member in zf.namelist():
        if member.find(pattern) != -1:
            print(member)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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