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
,上面的代码应该如何修改?
最简单的方法是:
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(文件的第一行)......
最后,为了额外的功劳,请考虑如何使这个工作在非常短的文件上! - )