`cat filename | grep -B 5 -C 5 foo`

gkw*_*gkw 2 python grep

for filename in os.listdir("."):
    for line in open(filename).xreadlines():
        if "foo" in line:
            print line
Run Code Online (Sandbox Code Playgroud)

所以这是一个简单的python相当于cat filename | grep foo.但是,我想相当于cat filename | grep -B 5 -C 5 foo,上面的代码应该如何修改?

Ale*_*lli 7

最简单的方法是:

for filename in os.listdir("."):
    lines = open(filename).readlines()
    for i, line in enumerate(lines):
        if "foo" in line:
            for x in lines[i-5 : i+6]:
                print x,
Run Code Online (Sandbox Code Playgroud)

添加行号,块之间的间隔等,以品尝;-).

在极不可能的情况下,你必须处理绝对令人发指的文本文件(比例如King James Bible大200-300倍,例如,整个文本文件大约是4.3 MB),我推荐一个生成器产生滑动窗口(线的"FIFO").只关注搜索行的简单性,不包括文件的第一个和最后几个(这需要一些特殊情况循环 - 这也是我返回索引的原因...因为它并不总是5 in那两个额外的循环! - ):

import collections

def sliding_windows(it):
  fifo = collections.deque()
  # prime the FIFO with the first 10 
  for i, line in enumerate(it):
    fifo.append(line)
    if i == 9: break
  # keep yielding 11-line sliding-windows
  for line in it:
    fifo.append(line)
    yield fifo, 5
    fifo.popleft()

for w, i in sliding_windows(open(filename)):
  if "foo" in w[i]:
    for line in w: print line,
Run Code Online (Sandbox Code Playgroud)

我想我会留下特殊情况循环(并且担心很少行的文件;-)作为练习,因为无论如何整个事情都是如此令人难以置信的假设.

只是一些提示......:关闭的"特殊情况循环"非常简单 - 只是反复删除第一行,而不是附加,显然,因为没有什么可以附加...索引应该仍然是5,当你刚刚产生一个窗口,其中5是最后一个索引(即文件的最后一行)时,你就完成了; 起始情况有点微妙,因为在读完前6行之前你不想屈服,此时索引将为0(文件的第一行)......

最后,为了额外的功劳,请考虑如何使这个工作在非常短的文件上! - )