Как использовать sed\awk для поиска определенных строк в файле, а затем для сопоставления всех последующих строк, соответствующих другому шаблону?

Как использовать sed\awk для поиска определенных строк в файле, а затем для сопоставления всех последующих строк, соответствующих другому шаблону?

Я нашел похожую тему, но не смог понять, как реализовать ее для собственного использования:

захватить несколько строк после соответствующей целевой строки

Вот в чем проблема:

Я пытаюсь реализовать это в своем проекте, но, похоже, не могу заставить это работать. Я использую Linux, может кто-нибудь разобрать?

По сути, я пытаюсь пройтись по пачке логов и захватить определенные строки вместе с их стеком\подробностями. Вот пример:

2020-01-20T05:58:19.119Z verbose vpxa[6E21B70] [Originator@6876 sub=PropertyProvider opID=k5cokp1a-928316-auto-jwal-h5:70047736-92-01-84] [CommitChangesAndNotify] Updating cached values
2020-01-20T05:58:19.119Z info vpxa[6E21B70] [Originator@6876 sub=Default opID=k5cokp1a-928316-auto-jwal-h5:70047736-92-01-84] [VpxLRO] -- ERROR task-107599 -- **vm-1178** -- vim.VirtualMachine.reconfigure: vmodl.fault.InvalidArgument:
--> Result:
--> (vmodl.fault.InvalidArgument) {
-->    faultCause = (vmodl.MethodFault) null,
-->    faultMessage = (vmodl.LocalizableMessage) [
-->       (vmodl.LocalizableMessage) {
-->          key = "msg.disk.extendFailure",
-->          arg = (vmodl.KeyAnyValue) [
-->             (vmodl.KeyAnyValue) {

Мне нужно будет захватить каждую строку, содержащую «vm-1178», и все последующие строки, начинающиеся с «-->», пока шаблон не изменится, затем начать поиск vm-1178 до следующего раза, когда это произойдет, и т. д.

Надеюсь, это имеет смысл. Спасибо!

решение1

Попробуй это,

awk '!/^-->/{p=0} /vm-1178/{p=1} p'
  • !/^-->/{p=0}: Устанавливайте var p(например, print) в 0 всякий раз, когда строка не начинается с -->.
  • /vm-1178/{p=1}: Устанавливать var p= 1 всякий раз, когда строка совпадает /vm-1178/.
  • p: Вывести строку всякий раз, когда pистинно (здесь=1)

решение2

awkДля этой цели можно использовать :

awk 'index($0,"vm-1178")>0 {in_pat=1; print; next} \
in_pat == 1 && $0 ~ /^-->/ {print; next} \
{in_pat=0}' logfile.txt

Он содержит три правила:

  • Первое правило будет искать строки, содержащие шаблон, и выводить их, а также устанавливать внутренний флаг in_patна 1.
  • Второе правило гласит, что все последующие строки, начинающиеся с , -->также будут напечатаны.
  • Третье правило используется для сброса этого флага на самой первой строке.нетсодержащие шаблон или не начинающиеся с -->, так что ничего не печатается, пока шаблон не будет найден снова.

Обратите внимание, что в первом правиле indexиспользуется функция, а не совпадение RegExp. Это сделано для того, чтобы вы также могли искать шаблоны, содержащие символы, имеющие особое значение в регулярных выражениях.

решение3

Используя Perl, это будет работать:

 perl -ne ' { $t=0 if ( !/^-->/ ); $t=1 if(/vm-1178/); print if($t); }' <filename>

Связанный контент