grep -r在python中

aar*_*acy 4 python grep

我想在python函数中实现unix命令'grep -r'.我知道commands.getstatusoutput(),但是现在我不想使用它.我想出了这个:

def grep_r (str, dir):
    files = [ o[0]+"/"+f for o in os.walk(dir) for f in o[2] if os.path.isfile(o[0]+"/"+f) ]
    return [ l for f in files for l in open(f) if str in l ]
Run Code Online (Sandbox Code Playgroud)

但那当然不使用正则表达式,它只是检查'str'是否是'l'的子串.所以我尝试了以下内容:

def grep_r (pattern, dir):
    r = re.compile(pattern)
    files = [ o[0]+"/"+f for o in os.walk(dir) for f in o[2] if os.path.isfile(o[0]+"/"+f) ]
    return [ l for f in files for l in open(f) if r.match(l) ]
Run Code Online (Sandbox Code Playgroud)

但这不起作用,即使前者的功能也没有给我任何匹配.改变了什么?我可以将它拆分成一堆嵌套循环,但我更感兴趣的是简洁而不是可读.

Joe*_*erg 9

您可能希望search()而不是match()在行中间捕获匹配项,如http://docs.python.org/library/re.html#matching-vs-searching中所述

此外,您的代码的结构和意图是非常隐藏的.我已经python化了它.

def grep_r (pattern, dir):
    r = re.compile(pattern)
    for parent, dnames, fnames in os.walk(dir):
        for fname in fnames:
            filename = os.path.join(parent, fname)
            if os.path.isfile(filename):
                with open(filename) as f:
                    for line in f:
                        if r.search(line):
                            yield line
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 6

re.match只检查字符串的开头.

使用re.search()

来自文档:

Python提供了两种基于正则表达式的不同原语操作:匹配仅在字符串的开头检查匹配,而搜索在字符串中的任何位置检查匹配(这是Perl默认执行的操作).