Mesclar linhas no arquivo junto de regex para “alinhar” arquivos de log de registro de múltiplas linhas

2

As ferramentas de linha de comando do Stadard unix (grep, cut, sed etc.) funcionam todas uma linha por vez. E quase sempre isso é ótimo.

No entanto, estou tentando analisar alguns logs de consultas lentas do postgresql. Cada entrada tem algumas coisas no início (data e hora, duração) e, em seguida, a consulta SQL. A consulta SQL pode ter novas linhas, portanto, cada "entrada" no arquivo de log pode levar mais de uma linha (desde que as novas linhas na consulta sejam colocadas diretamente no arquivo de log e não sejam ignoradas). Eu gostaria de de alguma forma "mesclar" essas linhas juntos, de modo que 1 linha = 1 entrada do arquivo de log. Agora, às vezes, uma entrada é totalmente em uma linha e, às vezes, uma entrada é distribuída em até 10 linhas.

Existe uma ferramenta unix que pode de alguma forma "alinhar" esse arquivo? Eu gostaria de dar um regex (PCRE) e ele irá dividir a linha / stdin com base nisso. Todas as novas linhas reais entre ocorrências dessa regex devem ser substituídas por "\n" ou algo que eu possa especificar.

Existe provavelmente um forro para fazer isso com o perl, mas eu gostaria de ver se alguém já fez esse programa antes de eu mesmo fazer isso.

UPDATE : eu poderia fornecer dados de amostra, mas gostaria de saber o problema genérico. Os SQL Servers podem potencialmente criar arquivos de log de várias linhas. Eu quero uma solução genérica para transformar qualquer arquivo em um arquivo de estilo unix-y separado por nova linha.

    
por Rory 07.04.2015 / 16:19

2 respostas

1

Usando o gawk, você pode usar uma expressão (subconjunto de) PCRE como separador de registro ( RS ), defina um separador de registro de saída diferente ( ORS ) e substitua \n .

Exemplo:

gawk 'BEGIN {RS="[ ]*;\n"; ORS="\n===\n"}
            {gsub("\n","\n");   print} '

neste exemplo:

  • registros são separados por [ ]*;\n na entrada
  • registros são separados por "\ n === \ n" na oputput
por 07.04.2015 / 19:23
0

Analise a linha do arquivo de log para linha e suprima todas as \ ns. Quando você vir uma nova entrada, primeiro escreva \ n, exceto pela primeira vez.
Você disse Each entry has some stuff at the start (datetime, duration) mas não deu um exemplo. Ok, eu chamarei de NEW_ENTRY, você pode modificar.

inStatement=0
cat logfile | while read -r line; do
   if [[ ${inStatement} = 0 ]]; then
      inStatement=1
   else
      [[ ${line} = NEW_ENTRY* ]] && echo
   fi
   echo -n "${line} "
done
echo
    
por 10.04.2015 / 00:36