Самый простой способ:
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,
добавить номера строк, разрывы между блоками и т. Д. По вкусу; -).
В крайне маловероятном случае, когда вам приходится иметь дело с совершенно огромными текстовыми файлами (например, в 200-300 раз больше, чем в Библии короля Иакова, что составляет около 4,3 МБ в целом в виде текстового файла), я рекомендовать генератор, создающий скользящее окно («FIFO» из линий). Сосредоточение для простоты только на поиске строк, исключая первые и последние несколько файлов (для этого требуется дополнительно несколько циклов специального случая - вот почему я также возвращаю индекс ... потому что это не всегда 5 в эти две дополнительные петли! -):
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,
Я думаю, что я оставлю циклы специального случая (и буду беспокоиться о файлах, состоящих из нескольких строк ;-), в качестве упражнений, поскольку все это так невероятно гипотетично.
Всего несколько подсказок ...: закрывающий "цикл особого случая" действительно прост - просто многократно удаляйте первую строку, не добавляя, очевидно, так как добавить больше нечего ... индекс все равно должен быть всегда 5, и вы закончили, когда вы только что дали окно, где 5 - последний индекс (т. е. последняя строка файла); начальный случай немного сложнее, так как вы не хотите уступать, пока не прочитаете первые 6 строк, и в этот момент индекс будет равен 0 (первая строка файла) ...
Наконец, для дополнительной оценки, подумайте, как заставить эту работу работать и с очень короткими файлами! -)