views:

145

answers:

3

Hi Alls,

I would like to build a small python script that basicaly does the reverse of grep. I want to match the files in a directory/subdirectory that doesn't have a "searched_string".

So far i've done that:

import os

filefilter = ['java','.jsp'] 
path= "/home/patate/code/project"
for path, subdirs, files in os.walk(path):
    for name in files:
        if name[-4:] in filefilter :
        print os.path.join(path, name)

This small script will be listing everyfiles with "java" or "jsp" extension inside each subdirectory, and will output them full path.

I'm now wondering how to do the rest, for example i would like to be able if I forgot a session management entry in one file (allowing anyone a direct file access), to search for : "if (!user.hasPermission" and list the file which does not contain this string.

Any help would be greatly appreciated !

Thanks

+1  A: 

To check if a file with a path bound to variable f contains a string bound to name s, simplest (and acceptable for most reasonably-sized files) is something like

with open(f) as fp:
    if s in fp.read():
        print '%s has the string' % f
    else:
        print '%s doesn't have the string' % f

In your os.walk loop, you have the root path and filename separately, so

f = os.path.join(path, name)

(what you're unconditionally printing) is the path you want to open and check.

Alex Martelli
Thanks Alex for your explaination !Unfortunatly i have some issue to run this :test.py:22: Warning: 'with' will become a reserved keyword in Python 2.6I then run it with python2.6, and get another error: File "test.py", line 18, in <module> if s in f.read():AttributeError: 'str' object has no attribute 'read'Thanks
thomytheyon
@thomytheyon: `f` is of `type` `str`, containing the filename. Try `if s in fp.read()`.
Johnsyweb
No more error but doesn't return anything :(
thomytheyon
Sorry for the typo, fixed (tx @johnsy). @thomy, I'm using `print` instead of `return`, of course you can edit that to perform exactly the actions you want instead, in either case.
Alex Martelli
A: 

Instead of printing file name call function that will check if file content do not match texts you want to have in source files. In such cases I use check_file() that looks like this:

WARNING_RX = (
    (re.compile(r'if\s+\(!\s+user.hasPermission'), 'user.hasPermission'),
    (re.compile(r'other regexp you want to have'), 'very important'),
    )

def check_file(fn):
    f = open(fn, 'r')
    content = f.read()
    f.close()
    for rx, rx_desc in WARNING_RX:
        if not rx.search(content):
            print('%s: not found: %s' % (fn, rx_desc))
Michał Niklas
A: 

I'm trying to get alex code to work, unfortunatly I'm a python beginner :(

I'm probably doing something wrong :

import sys,os

filefilter = ['.xml','java','.jsp','lass']

path= "/home/patate/code/project"

s = "helloworld"

for path, subdirs, files in os.walk(path):

for name in files:
    if name[-4:] in filefilter :
       f = str(os.path.join(path, name))
       with open(f) as fp:
           if s in f.read():
              print "%s has the string" % f
           else:
              print "%s doesn't have the string" % f

It exit with :

Traceback (most recent call last):

File "test.py", line 18, in

if s in f.read():

AttributeError: 'str' object has no attribute 'read'

Thanks for your help !

thomytheyon
`f` is of type `str`, containing the filename. Try `if s in fp.read()`.
Johnsyweb
No more error, but doesn't return anything, and it should return a bunch of match
thomytheyon
The code as given prints exactly one line per applicable file (doesn't _return_ anything, but _print_s a lot;-), so if it's not printing anything it means it's not finding any applicable file -- if that's the case add more `print`s (e.g. adding an `else` branch for this debugging purpose to the `if name[-4:] in filefilter`) to help you understand what's going on.
Alex Martelli