Python или bash-скрипт: если паттерн в строках между двумя одинаковыми маркерами, убрать строки и первый маркер

1

Как новичок, я пытаюсь решить следующую проблему (сценарий 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

Я попытался решить его с помощью регулярного выражения или awk (это очень застенчивое начало)

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

но мне трудно понять, как реализовать это в функции, которая решила бы всю проблему. Это сделало бы меня очень счастливым, если бы кто-то мог мне помочь!

ура

Теги:
design-patterns
marker
lines

1 ответ

0
Лучший ответ

Вот способ сделать это в 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: Здесь потоковая версия (лучше подходит для больших файлов.) Она использует islice из itertools для получения 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()
  • 0
    Спасибо! Я постараюсь адаптировать это от того, что вы написали.
  • 0
    Вы не упоминали, что это было 50G раньше - вместо этого вы захотите потоковую передачу, которая читает и пишет одновременно.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню