Use sed para escolher uma entrada de log potencialmente multilinha

1

Estou tentando criar um comando sed para escolher uma única entrada de log dos nossos registros do servidor de aplicativos.

Os registros estão neste formato:

LOG|2016-07-26_15:37:45:536|entry1|!
LOG|2016-07-26_15:37:45:536|entry2|extra data
on new line|!
LOG|2016-07-26_15:37:45:536|entry3|!
LOG|2016-07-26_15:37:45:536|entry4|!
LOG|2016-07-26_15:37:45:536|entry5|!

Como você pode ver, algumas entradas serão apenas uma linha e algumas terão várias linhas contendo dados extras. Uma entrada sempre começa com o tipo de log (simplificado para apenas "LOG" acima) e sempre termina com |!

Agora, isso é o que eu tenho até agora:

sed -n -e '/'$id'/,/|!/ p'

Isso funciona bem para as entradas de log de várias linhas:

$ cat log | sed -n -e '/entry2/,/|!/ p'
LOG|2016-07-26_15:37:45:536|entry2|extra data
on new line|!

Mas não tão bem para as entradas de linha única, pois também exibe a próxima entrada:

$ cat log | sed -n -e '/entry3/,/|!/ p'
LOG|2016-07-26_15:37:45:536|entry3|!
LOG|2016-07-26_15:37:45:536|entry4|!

Alguma idéia de como eu posso modificar meu sed acima para cobrir entradas de registro de linha única ou múltipla?

    
por yzfr1 27.07.2016 / 08:49

2 respostas

1

Você precisa lidar com os casos separadamente, por exemplo:

sed -n '/entry3.*[^!]$/, /|!/p; /entry3.*!/p ' log

Se uma linha corresponder ao id e terminar com um ponto de exclamação, ela será impressa. Se uma linha corresponder ao id e não terminar com um ponto de exclamação, marcará o início de um intervalo de endereços.

    
por 27.07.2016 / 09:27
3

Outro caminho pode ser o loop da linha correspondente até o final da entrada:

sed '/entry3|/{:a;/!$/!{n;ba;};p;};d' log
    
por 27.07.2016 / 10:06