Я запускаю следующую команду для файла журнала и хочу получить только последнее / последнее совпадение. Иногда может быть только одно совпадение, в других случаях может быть несколько, что вызывает у меня проблему, поскольку следующая команда возвращает оба совпадения:
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} } }'
- только события «ТЕСТ = МОЩНОСТЬ».