Извлечь несколько строк, если они совпадают

Причина, по которой сценарий оболочки не обеспечивает полноценный пользовательский интерфейс, заключается в том, что отклик пользовательского интерфейса будет медленным, поскольку сценарий оболочки состоит из файлов сценария, а не двоичных файлов. Решение состоит в том, чтобы использовать Python (или любой другой язык) для создания пользовательского интерфейса переднего плана, а затем вызывать в нем скрипты.

5
17.01.2019, 17:27
3 ответа

Следующее будет соответствовать тегу, указанному в переменной тега:

awk -v tag=P1-DIMMD1 '/ID    SIZE TYPE/ { block = $0; output = 0; next } { block = block "\n" $0 } /Location Tag/ { output = ($0 ~ tag) } /Configured Voltage/ && output { print block }'

Сценарий AWK

/ID    SIZE TYPE/ {
  block = $0
  output = 0
  next
}

{ block = block "\n" $0 }

/Location Tag/ { output = ($0 ~ tag) }

/Configured Voltage/ && output { print block }

Мы накапливаем блок в переменной block, и выводим его, когда доходим до конца блока, если увидели в процессе нужный тег.

6
27.01.2020, 20:33

Вдохновленный отличным ответом @Stephen Kitts, я написал немного более общий сценарий для выполнения сопоставления блоков при наличии заданного начального и конечного шаблонов.

#!/usr/bin/awk -f
BEGIN {
    pstart=ARGV[1];
    pstop=ARGV[2];
    pmatch=ARGV[3];
    ARGV[1]=ARGV[4];
    ARGC=2;
}
$0 ~ pstart { block = $0; output = 0; next }
{ block = block "\n" $0 }
$0 ~ pmatch { output = 1 }
$0 ~ pstop && output { print block; output = 0 }

Использование:match_block START END MATCH [FILE]

./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' f

или

command |./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'

Спасибо, что предложили написать это как скрипт awk. Мой исходный сценарий оболочки был:

#!/bin/sh

[ -z "$4" ] && file="-" || file="$4"

awk \
  -v BLOCKSTART_PATTERN="$1" \
  -v BLOCKEND_PATTERN="$2" \
  -v BLOCKMATCH_PATTERN="$3" \
  '
  $0 ~ BLOCKSTART_PATTERN { block = $0; output = 0; next }
  { block = block "\n" $0 }
  $0 ~ BLOCKMATCH_PATTERN { output = 1 }
  $0 ~ BLOCKEND_PATTERN && output { print block; output = 0 }
  ' "$file"

Использование:match_block START END MATCH [FILE].
Если файл не указан, будет использоваться stdin.

В вашем случае:

command |./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'

или

./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' file
2
27.01.2020, 20:33

Можно использовать ed ... и sed, чувак!

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

  1. command > dimm-output
  2. wanted=P1-DIMMD1
  3. ed -s dimm-output <<< $'/Location Tag: '"$wanted"$'\n?^ID.*SIZE.*TYPE\n.,/Configured Voltage/p\nq\n' | sed 1,2d

Строка команды ed-разбивается на четыре\n-разделенных команды:

  1. поиск вперед, используя /, для текста «Тег местоположения :», за которым следует значение переменной $wanted
  2. поиск в обратном направлении, используя ?, для шаблона:(начало -строки -), "ID", что угодно, "РАЗМЕР", что угодно, "ТИП"
  3. от этой строки(.)до(,)следующей строки, которая соответствует «Настроенному напряжению», распечатайте эти строки(p)
  4. уволился:q

Поскольку ed auto -выводит совпадающую строку при поиске, я использовал здесь sed, чтобы удалить эти две строки.

4
27.01.2020, 20:33

Теги

Похожие вопросы