Как вывести все строки, соответствующие шаблону 1, и только одну строку перед ней, соответствующую шаблону 2?

Как извлечь строки из данных с помощью Perl

В этой статье мы рассмотрим, как из текста извлечь определенные строки, основываясь на шаблонах. Мы разберем решение, используя язык программирования Perl, что позволит эффективно обрабатывать текстовые файлы и извлекать необходимую информацию.

Задача: Извлечение строк с помощью шаблонов

Предположим, у вас есть текстовый файл, содержащий строки разной информации, и вам нужно извлечь следующие данные:

  1. Все строки, содержащие текст "someheader".
  2. Строки, предшествующие строке, содержащей определенный шаблон (например, "zzz" или "yyy").
Пример исходных данных:
USA someheader
xxx
yyy
zzz
UK someheader
aa
xxx
zzz
INDIA someheader
xx
sss
yyy
Ожидаемый вывод:

Для поиска строк, содержащих "zzz":

USA someheader
zzz
UK someheader
zzz

Для поиска строк, содержащих "yyy":

USA someheader
yyy
INDIA someheader
yyy

Решение с использованием Perl

Для решения поставленной задачи можно использовать следующий Perl-скрипт:

$h=$_ if /someheader/; 
print $h,$_ if /xxx/;

Этот код выполняет следующие операции:

  • Если строка содержит "someheader", она сохраняется в переменной $h.
  • Если строка содержит "xxx", выводится сохраняемое значение $h и сама строка.
Пример выполнения кода:

Запустив следующий код, вы получите требуемые результаты:

perl -ane '$h=$_ if /someheader/;print $h,$_ if /xxx/' file

Альтернативное решение с помощью Sed

Если вы предпочитаете использовать утилиту sed, вот еще одно решение:

<data sed -n '
   /someheader/ {h;d}
   /zzz/ {
      x
      /./ p
      s/.*//
      x
      p
      d
   }
'
Объяснение работы кода:
  1. Если текущая строка содержит "someheader", эта строка копируется в поток сохранения и не печатается.
  2. Если текущая строка содержит "zzz":
    • Сначала происходит обмен содержимого между пространствами.
    • Если поток сохранения не пуст, он выводится, показывая заголовок перед содержимым с "zzz".
    • Затем попытка очистить память потока для предотвращения повторного вывода.

Примечания по коду

  • Обратите внимание, что строки, содержащие "someheader", будут рассматриваться как заголовки, даже если они содержат "zzz". Чтобы изменить это поведение, измените порядок условий в коде.
  • Данное решение предоставляет гибкость для анализа данных, даже если они выглядят не совсем стандартно.
Пример неструктурированных данных:
zzz without header
USA someheader
xxx
yyy
zzz
UK someheader
ambiguous someheader zzz   # a header or a non-header?
aa
xxx
zzz
bzzz                       # multiple zzz under one header
INDIA someheader
xx
sss
yyy

Таким образом, используя представленные решения на Perl и Sed, вы сможете эффективно извлекать необходимую информацию из текстовых файлов, что может быть полезно в различных приложениях обработки данных.

Источник

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *