Использование sed в Linux для извлечения строк из файла журнала - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть файл журнала, который печатает следующие строки:

01:15:21.882 DEBUG [SampleProcess] 
Sample Message
01:15:21.882 DEBUG [SampleProcess1] 
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0
01:15:21.883 DEBUG [SampleProcess2] 

Мне удалось извлечь сводный отчет с помощью приведенной ниже команды sed

 sed -n '/Summary Report/,/Sample Text4/p' samplefile.log 

Однако я такжехотите напечатать метку времени, когда был сформирован пример отчета.

Итак, в настоящее время с

sed -n '/Summary Report/,/Sample Text4/p' samplefile.log

Я вижу вывод как

Summary Report
    Sample Text1: 126
    Sample Text2: 2330
    Sample Text3: 2331
    Sample Text4: 0

Я хочу вывод как

01:15:21.882 DEBUG [SampleProcess1] 
    Summary Report
    Sample Text1: 126
    Sample Text2: 2330
    Sample Text3: 2331
    Sample Text4: 0

Ответы [ 5 ]

0 голосов
/ 30 сентября 2018
awk '/Sample Message/{getline;print}/^S/' file

01:15:21.882 DEBUG [SampleProcess1] 
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0
0 голосов
/ 30 сентября 2018

Вы можете использовать perl для извлечения файла из файла:

$ perl -0777 -lnE 'while (/^(?=[\d.:]+[ \t]+DEBUG[^\n]*$)(.+?)(?=^[\d.:]+[ \t]+DEBUG|\z)/gms)
                 { $s=$1; 
                   say "$s" if $s =~ m/^Sample Text4/ms  }' file
01:15:21.882 DEBUG [SampleProcess1] 
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0

Это работает с двумя предвидениями ^(?=[\d.:]+[ \t]+DEBUG[^\n]*$), которые разделяют пример на три блока, разделенных линией со DEBUG в нем.

DEMO

Как только у вас есть каждый блок, вы можете проверить, находится ли подстрока внутри этого блока, с помощью

m/^Sample Text4/ms

Если подстрока найденараспечатать блок.


Вот решение POSIX sed, которое включает в себя обращение файла (с tail -r), поиск двух шаблонов в обратном порядке, а затем повторную сборку файла в исходном порядке:

$ tail -r file.log | sed -n '/^Sample Text4/,/DEBUG/p' | tail -r    

(Добавление -r к tail является довольно недавним добавлением POSIX и может отсутствовать в вашей ОС. Это в последних выпусках BSD и OS X.)

0 голосов
/ 28 сентября 2018

Вы можете попробовать

sed -n '/Process1/{:a;N;/^\n/s/^\n//;/Sample Text/{p;s/.*//;};ba};' samplefile.log

Проверить эту ссылку: https://unix.stackexchange.com/questions/47942/how-to-get-all-lines-between-first-and-last-occurrences-of-patterns

0 голосов
/ 30 сентября 2018

sed - для выполнения s / old / new , что все .Для всего остального вы должны использовать awk:

$ awk '
    /DEBUG/ { prt() }
    { rec = rec $0 ORS }
    END { prt() }
    function prt() {
        if (rec ~ /Summary Report/) {
            printf "%s", rec
        }
        rec = ""
    }
' file
01:15:21.882 DEBUG [SampleProcess1]
Summary Report
Sample Text1: 126
Sample Text2: 2330
Sample Text3: 2331
Sample Text4: 0

Создать запись всех строк с момента последнего вызова prt ().Каждый раз, когда вы видите строку DEBUG или в конце ввода, распечатайте запись, если необходимо.

Это будет работать при использовании любого awk в любой оболочке в любой системе UNIX.

Ясно, просто,прочный, эффективный, портативный, расширяемый и т. д.

0 голосов
/ 28 сентября 2018

Это может работать для вас (GNU sed):

sed -n '/^..:..:..\./{N;/Summary Report/!D;:a;N;/Sample Text4/!ba;s/\n/&    /gp}' file

Отключить автоматическую печать.Если текущая строка является временной меткой, а следующая не является Summary Report, удалите первую строку и повторите.В противном случае, соберите следующие строки до Sample Text4, сделайте отступ для всех строк, кроме первой, напечатайте и повторите.

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