Awk: печать между рисунками в одной строке и обратный порядок совпадающей строки - PullRequest
1 голос
/ 27 марта 2020

У меня есть файл журнала службы приложения, и я пытаюсь извлечь трассировку стека, созданную одним из его дочерних процессов. Трассировки стека имеют совершенно иной шаблон, чем обычные файлы журналов.

Обычные записи файла журнала веб-приложения:

2020-03-26 08:31:05.000 : INFO : (18582) : (SERVICE) : MSG_1234 : Process id 98765. Standard output and error:

Пример трассировки стека:

7f318820d000-7f318a106000 rwxp 00000000 00:00 0                          [stack:10002]
7f318a106000-7f318a107000 ---p 00000000 00:00 0 

Мне нужно извлечь следы стека, что я могу сделать. Проблема со следами стека состоит в том, что они выгружаются в обратном порядке. Каждый выгруженный блок упорядочен, но блоки выгружаются в обратном порядке.

Вот пример того, как я извлекаю блоки (ПРИМЕЧАНИЕ: шаблоны запуска и остановки находятся в одной строке):

echo "STOP message START
five
six
STOP message START
three
four
STOP message START
one
two
STOP message" | awk '/START/ {flag=1; next} flag; /STOP/ {flag=0}'

Это вывод:

five
six
three
four
one
two
STOP message

Хотя я хотел бы получить это:

one
two
three
four
five
six

Я могу жить с последним совпавшим "сообщением STOP" , но мне нужно, чтобы блоки были в порядке.

1 Ответ

2 голосов
/ 27 марта 2020

Если вы начнете с этого, чтобы пронумеровать каждый блок и строки в каждом блоке по мере их нахождения, вы можете впоследствии отсортировать строки, как вам нравится, используя sort, а затем удалить добавленные вами числа, используя cut: * 1003. *

$ awk -v OFS='\t' '/STOP/{lineNr=0} lineNr{print blockNr, lineNr++, $0} /START/{blockNr++; lineNr=1}' file
1       1       five
1       2       six
2       1       three
2       2       four
3       1       one
3       2       two

например:

$ awk -v OFS='\t' '/STOP/{lineNr=0} lineNr{print blockNr, lineNr++, $0} /START/{blockNr++; lineNr=1}' file |
    sort -k1,1nr -k2,2n
3       1       one
3       2       two
2       1       three
2       2       four
1       1       five
1       2       six

$ awk -v OFS='\t' '/STOP/{lineNr=0} lineNr{print blockNr, lineNr++, $0} /START/{blockNr++; lineNr=1}' file |
    sort -k1,1nr -k2,2n | cut -f3-
one
two
three
four
five
six
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...