Python 或 bash 脚本:如果模式在两个相同标记之间的线条中,删除线条和第一个标记

Python or bash script: if pattern in lines between two identical markers, remove lines and first marker

作为初学者,我正在尝试解决以下问题(bash 或 python 脚本):

文件(~50G!):

marker
xxx
xxx
xxx
pattern
marker
xxx
xxx
xxx
marker
xxx
xxx
xxx
pattern

我想找到一种方法来删除两个 markers + 第一个 marker 之间的线,但不是最后出现的 marker IF no pattern 可以在整行中找到。

想要的结果:

marker
xxx
xxx
xxx
pattern
[empty!]
marker
xxx
xxx
xxx
pattern

我尝试用正则表达式或 awk 解决它(这是一个非常害羞的开始)

awk '/marker/{f=1} f; /marker/{f=1}' file

但我很难理解如何在可以解决整个问题的函数中实现它。如果有人能帮助我,我会很高兴!

干杯

这是 python 中的一种方法。将 marker 视为分隔符,然后从不包含 pattern

的文本片段中删除任何内容
f = open('markerfile.txt','r')

lines = f.read().split('marker\n')
lines = [entry for entry in lines if 'pattern' in entry or not entry]
print 'marker\n'.join(lines)

编辑:列表理解中的 or not entry 位仅处理 marker 是文件第一行的情况。

编辑 2:这是一个流式版本(更适合大文件。)它使用 itertools 中的 islice 一次获取文件的 n 行。算法的其余部分大致相同。

from itertools import islice

f = open('markerfile.txt','r')
fout = open('markersout.txt','w')

n=5
while True:
    next_n_lines = ''.join(list(islice(f, n)))
    if not next_n_lines:
        break
    lines = next_n_lines.split('marker\n')
    lines = [entry for entry in lines if 'pattern' in entry or not entry]
    print >> fout, 'marker\n'.join(lines).strip()

f.close()
fout.close()