Назад | Перейти на главную страницу

Grep последнее совпадение из файла

Я запускаю следующую команду для файла журнала и хочу получить только последнее / последнее совпадение. Иногда может быть только одно совпадение, в других случаях может быть несколько, что вызывает у меня проблему, поскольку следующая команда возвращает оба совпадения:

cat "$(ls -t | head -n1)" | grep -P "(NODE1[\s\S]*TEST\s=\sPOWER[\s\S]*OUTPUT\s=\s\d+?.*\s+;?)"

>>>>> (results in)...

NODE1 2018-03-06 12:01:23
  TEST = POWER
  EVENT_TIME = 2018-03-06 12:01:23
  OUTPUT = 12

;

NODE1 2018-03-06 12:03:23
  TEST = POWER
  EVENT_TIME = 2018-03-06 12:03:23
  OUTPUT = 7

;

Мне нужна последняя подходящая группа, если их несколько. Возможно ли это с помощью grep / regex или мне нужно передать результаты в sed / awk? Если да, то как?

По совету Юрия я начал изучать использование tac вместо кота, и перевернув мой grep заявление. Теперь я смотрю на файл снизу вверх и хватаю первое совпадение:

tac "$(ls -t | head -n1)" | grep -m 1 -P "\d+[\s\S]*TEST\s=\sTXPOWER" | tac

я нахожу perl для этого удобнее:

perl -lane 'if(/^NODE1 /&&($#n=-1)../^;$/){push @n,$_} END{print $_ for @n}' file

Пояснение:

perl Практический язык извлечения и отчетности.
-lane переключатели обычно полезны для однострочников.
' запуск собственно программных инструкций
if(/^NODE1 /&&($#n=-1)../^;$/) рассматривать только части текста, начинающиеся со строки, начинающейся с NODE1 с последующим пробелом и в конце строки, содержащей одну точку с запятой.
/^NODE1 /&&($#n=-1) сбросить @n массив в начале текстовой части.
{push @n,$_} сохранить каждую строку в текстовой части как элемент массива с именем @n
END{print $_ for @n} когда весь файл будет проанализирован, распечатайте текстовую часть, сохраненную в @n.
' конец инструкции программы.
file это заполнитель для имени файла, который вы хотите обработать.

Предлагаю вам такое решение:

cat <your_source_file> | sed -n '/NODE1/,/;/p' | tr '\n' '|' | awk -F ';' '{print $(NF-1)}'|tr '|' '\n'

sed -n '/NODE1/,/;/p' - найти блоки «NODE1».

tr '\n' '|' преобразовать символы новой строки в разделитель записей, поэтому столбцы таблицы будут разделены символом ';'.

awk -F ';' '{print $(NF-1)}' - распечатать последний столбец таблицы.

tr '|' '\n' - вернуться к предыдущему просмотру для записи.

awk -F ';' '{for(i=(NF-1); i>0; i--){ if($i ~ "TEST = POWER"){print $i} } }' - только события «ТЕСТ = МОЩНОСТЬ».