2015-01-07 3 views
0

Надеюсь, вы сможете пролить свет в одном из моих требований. Пусть говорят, у меня есть файл со следующими записями:Отображение нескольких строк с использованием нескольких шаблонов

 
ABC 123 
XYZ 789 
XYZ 456 
ABC 234 
XYZ 789 
ABC 567 
XYZ 789 
XYZ 678 
XYZ 123 

В принципе, у меня есть строки ABC с X числа строк XYZ после него. Количество записей XYZ в каждой ABC варьируется от 1 до многих.

Мне нужен сценарий оболочки, который будет выводить ABC и соответствующий XYZ на основе шаблонов во втором столбце.

Например, отображать записи ABC с рисунком 567 и соответствующий XYZ записи с рисунком 678.

Выход должен быть только:

 
ABC 567 
XYZ 678 
+0

Вы хотите найти ABC и 567 (на примере) в буквальном смысле? –

+0

Не должен ли запрос для 567 найти все три из следующих линий XYZ, а не только средний? –

ответ

0

попробовать это, если он работает для вас. Я надеюсь, что я понял ваше требование право:

awk -v p1='ABC 567' -v p2='XYZ 678' 
     '$0~p1{t=1;print;next}/^ABC/{t=0}$0~p2&&t' file 
+0

Привет, Кент, я забыл упомянуть, что у меня есть длинный список шаблонов для запуска – Ravenwolf

0

Чтобы решить эту проблему, я использую awk массировать данные в одну линию, то grep на этом выходе, затем sed вернуться соответствующие записи в оригинальном формате.

awk '{ printf ($1 == "ABC" ? "\n" : " @¶@ ") $0 }' file |grep 567 |sed 's/ @¶@ /\n/g' 

Код ходьбы:

  • Я использовал @¶@ в качестве разделителя. Используйте то, что не будет иметь конфликтов в ваших данных (в противном случае вам придется иметь дело с побегом). Также обратите внимание, что ваш пробег в поддержку UTF8 может отличаться.
  • awk принты, без закрывающего разрыв строки, две вещи сцепляются:
    • Если мы на линии ABC, линия перерыв (\n). В противном случае разделитель (@¶@).
    • Тогда существующая линия ($0)
  • grep затем бежит по вашему запросу. Это позволяет использовать -f FILE_OF_PATTERNS или коллекция -e PATTERN s
  • sed затем возвращаются разделители обратно к исходному формату

Это имеет то преимущество, что происходит построчно. Если у вас есть десятки тысяч XYZ в одном ABC, это будет немного медленнее, но это не сохраняет ничего в памяти, поэтому это должно быть довольно масштабируемым.

Вот выход выше awk команды (да, есть ведущая пустая строка, которая не имеет значения):

$ awk '{ printf ($1 == "ABC" ? "\n" : " @¶@ ") $0 }' file 

ABC 123 @¶@ XYZ 789 @¶@ XYZ 456 
ABC 234 @¶@ XYZ 789 
ABC 567 @¶@ XYZ 789 @¶@ XYZ 678 @¶@ XYZ 123 
Смежные вопросы