【问题标题】:Python or bash script: if pattern in lines between two identical markers, remove lines and first markerPython 或 bash 脚本:如果模式在两个相同标记之间的行中,则删除行和第一个标记
【发布时间】:2018-06-20 21:02:06
【问题描述】:

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

文件(~50G!):

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

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

想要的结果:

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

我尝试用 regex 或 awk 来解决它(这是一个非常害羞的开始)

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

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

干杯

【问题讨论】:

  • 你想要empty 行吗?
  • @user3483203 没有!感谢阅读!

标签: python bash design-patterns marker lines


【解决方案1】:

这是一种在 python 中执行此操作的方法。将marker 视为分隔符,然后从文本sn-ps 中删除不包含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:这是一个流版本(更适合大文件。)它使用来自 itertoolsislice 一次获取文件的 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()

【讨论】:

  • 谢谢!我会尝试根据你写的内容改编它。
  • 您之前没有提到它是 50G - 您需要一个流式传输选项,而不是同时读取和写入。
  • 更新了我的答案以包含流媒体版本。
  • 不,我没有;认为它可能不相关,但它是!谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
相关资源
最近更新 更多