Grep файл в обратном порядке от определенной строки в файле - PullRequest
2 голосов
/ 22 апреля 2020

У меня есть такие журналы

2019-11-14T20:03:48.917Z  INFO Thread1 Audit ... Operation status="success" ... id=dad69655-07d0-4daf-a639-b8e3257fa6bd msg...
2019-11-14T20:03:48.908Z  INFO Thread Audit Operation status="success" ... id=67ab8c3b-b57c-4328-b483-81582be0341d msg...
2019-11-14T20:03:48.909Z  INFO Thread Audit ... Operation status="success" ...  id=b0485887-004a-4f55-b287-f5c9cf609787 msg...
2019-11-14T20:03:48.911Z  INFO Thread2 Audit ... Operation status="success" ... id=35ca8c14-757f-474a-a929-494781c4679f msg...
2019-11-14T20:03:48.915Z  INFO Thread2 Audit ... Operation status="failure" ... id=72f73c66-da37-11e9-8d68-005056bce6a5 msg...
2019-11-14T20:03:48.917Z  INFO Thread1 Audit ... Operation status="success" ... id=26ece804-da3a-11e9-bfed-005056bce25b msg...
2019-11-14T20:03:48.919Z  INFO Thread Not ... Operation status="failure" ... id=1b31f53f-66d5-475f-ace3-ed1905e8f818 msg...
2019-11-14T20:03:48.921Z  INFO Thread Not ... Operation status="success" ... id=84ee4947-633f-4ccb-832e-7b380052401c msg...
2019-11-14T20:03:48.948Z  INFO Thread Audit ... Operation status="failure" ... id=26ece804-da3a-11e9-bfed-005056bce25b msg...
2019-11-14T20:03:48.950Z  INFO Thread Audit ... Operation status="success" ... id=8837cb5f-48f5-49db-8ade-a47b96527501 msg...

... означает, что между ними может быть что угодно, ... также может иногда быть одним пробелом.

msg... означает, что id не всегда находится в конце строки, msg... также может иногда быть нулевым.

На самом деле это довольно сложно, но основная структура c такова.

Ввод - Мой ввод - это заданный идентификатор.

и

Условие - условие состоит в том, чтобы просмотреть строку журнала, содержащую этот идентификатор, чей OPstatus равен ошибка и относится к классу Audit.

Найдя эту строку журнала, возьмите ее поток и возьмите все журналы, принадлежащие этому потоку, до предыдущего журнала аудита этого потока.

Итак, Input указаны строки журнала и идентификатор = 26ece804-da3a-11e9-bfed-005056bce25b.

Вывод Я ожидаю, что это

2019-11-14T20:03:48.909Z  INFO Thread Audit ... Operation status="success" ...  id=b0485887-004a-4f55-b287-f5c9cf609787
2019-11-14T20:03:48.919Z  INFO Thread Not ... Operation status="failure" ... id=1b31f53f-66d5-475f-ace3-ed1905e8f818 msg...
2019-11-14T20:03:48.921Z  INFO Thread Not ... Operation status="success" ... id=84ee4947-633f-4ccb-832e-7b380052401c msg...
2019-11-14T20:03:48.948Z  INFO Thread Audit ... Operation status="failure" ... id=26ece804-da3a-11e9-bfed-005056bce25b msg...

То, что я пробовал это -

awk '{if($0~/.*Audit.*26ece804-da3a-11e9-bfed-005056bce25b.*/) system("grep -w " $3 " " FILENAME "| sed \"0,/.*Audit.*Operation status="success".*/d\" | sed \"/Operation status="failure"/{n;d;}\"" )}' file.log

Пожалуйста, помогите!

Ответы [ 3 ]

5 голосов
/ 22 апреля 2020

Perl на помощь!

perl -lane 'push @{ $h{ $F[2] } }, $_;
     if ("Audit" eq $F[3]) {
         print join "\n", "", @{ $h{ $F[2] } } if /status="failure"/;
         splice @{ $h{ $F[2] } }, 0, -1;
     }' -- file.log
  • -n читает строку ввода строкой
  • -l удаляет символы новой строки из ввода и добавляет их обратно в вывод
  • -a разбивает входные данные на пробел в массив @F
  • Каждая строка сохраняется в га sh с ключом имени потока (третий столбец, т.е. $F[2])
  • Если четвертый столбец $F[3] равен Audit и строка содержит уведомление об ошибке, мы печатаем все ранее записанные строки аудита для того же потока
  • При добавлении новой строки аудита в ха sh, мы удаляем все предыдущие (см. splice )

Другими словами, мы сохраняем все строки аудита для имени потока и печатаем предыдущие для каждая неудачная проверка.

4 голосов
/ 22 апреля 2020

с использованием awk

awk '{if($NF=="failure") system("grep -w " $3 " "  FILENAME)}'  filename.txt

Демонстрация:

$cat file1.txt
2019-11-14T20:03:48.909Z  INFO Thread Audit OPstatus = success
2019-11-14T20:03:48.911Z  INFO Thread2 Audit OPstatus = success
2019-11-14T20:03:48.915Z  INFO Thread2 NotAudit OPstatus = success
2019-11-14T20:03:48.917Z  INFO Thread1 NotAudit OPstatus = success
2019-11-14T20:03:48.919Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.921Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.948Z  INFO Thread Audit Opstatus = failure
$awk '{if($NF=="failure") system("grep -w " $3 " "  FILENAME)}'  file1.txt
2019-11-14T20:03:48.909Z  INFO Thread Audit OPstatus = success
2019-11-14T20:03:48.919Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.921Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.948Z  INFO Thread Audit Opstatus = failure
$

Объяснение:

NF <- Количество полей в текущей строке <br>$NF <- Последнее поле </p>

if($NF=="failure") <- Проверить, имеет ли последнее поле значение в качестве ошибки </p>

system() <- используется для вызова системной команды </p>

FILENAME <- встроенная переменная awk, которая содержит имя входного файла. Обратите внимание, что вы передаете ввод с помощью <code><, то есть стандартного ввода, тогда его значение будет -

grep -w " $3 " " FILENAME grep для 3-го поля входного файла и вывода на печать

----- -------------------------------------------------- ----------------

РЕДАКТИРОВАТЬ

--------------------- --------------------------------------------------

awk '{if($NF=="failure") system("grep -w " $3 " " FILENAME "| sed \"0,/Audit OPstatus.*success/d\" | sed \"/failure/{n;d;}\"" )}'

Демонстрация:

$awk '{if($NF=="failure") system("grep -w " $3 " " FILENAME "| sed \"0,/Audit OPstatus.*success/d\" | sed \"/failure/{n;d;}\"" )}' file1.txt 
2019-11-14T20:03:48.909Z  INFO Thread Audit OPstatus = success
2019-11-14T20:03:48.919Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.921Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.948Z  INFO Thread Audit Opstatus = failure
$

Объяснение:

sed "0,/Audit OPstatus.*success/d" <- Удалить все строки от начала до шаблона </p>

sed "/failure/{n;d;}" <- Удалить все строки из шаблона (исключая сопоставленную строку) до конца <code>n используется для перехода к следующей записи

0 голосов
/ 22 апреля 2020

Это работает для вашего конкретного примера:

grep ".*Thread .*= \(success\|failure\)" filename.txt

... дает:

2019-11-14T20:03:48.909Z  INFO Thread Audit OPstatus = success
2019-11-14T20:03:48.919Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.921Z  INFO Thread NotAudit OPstatus = success
2019-11-14T20:03:48.948Z  INFO Thread Audit Opstatus = failure

однако, вы можете посмотреть на обобщение этого в сценарии bash: вперед. Вот пример соответствия, которое я использовал . Regex101 - отличный инструмент для поиска решений подобных проблем.

РЕДАКТИРОВАТЬ:

Чтобы сделать это условно, просто поместите это в скрипт bash:

#!/usr/bin/env bash
grep -q ".*$1 .*= failure" $2
if [ $? -eq 0 ]; then
  grep ".*$1 .*= \(success\|failure\)" $2
fi

и запустить, например: ./check.sh Thread filename.txt

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...