Em sed ou awk, como faço para lidar com separadores de registro que * pode * abranger várias linhas?

StackOverflow https://stackoverflow.com/questions/310191

  •  10-07-2019
  •  | 
  •  

Pergunta

Meu arquivo de log é:

 Wed Nov 12 blah blah blah blah cat1
 Wed Nov 12 blah blah blah blah
 Wed Nov 12 blah blah blah blah 
 Wed Nov 12 blah blah blah blah cat2
     more blah blah
     even more blah blah
 Wed Nov 12 blah blah blah blah cat3
 Wed Nov 12 blah blah blah blah cat4

Eu quero analisar as entradas de várias linhas completas onde o gato é encontrado na primeira linha. Qual é a melhor maneira de fazer isso em sed e / ou awk?

i. eu quero minha análise a produtos:

 Wed Nov 12 blah blah blah blah cat1
 Wed Nov 12 blah blah blah blah cat2
     more blah blah
     even more blah blah
 Wed Nov 12 blah blah blah blah cat3
 Wed Nov 12 blah blah blah blah cat4
Foi útil?

Solução

Se você dizer que cada linha que começa com o espaço é uma continuação da folling sua fácil com (g) awk (este é da minha memória, talvez por isso, contém alguns erros menores, e para melhor legibilidade com algumas quebras de linha adicionais):

awk " BEGIN { multiline = 0;} 
      ! /^ / { if (whatever) 
                 { print; multiline = 1;} 
               else 
                 multiline = 0; 
             } 
        /^ / {if (multiline == 1) 
                 print;
             } 
     " 
      yourfile

onde whatever é seu cheque se a sua saída deve acontecer (por exemplo, para o gato).

Outras dicas

Assumindo que o seu arquivo de log não contém o '\01' caracteres de controle e '\02', e que uma linha contínua começa com exatamente quatro espaços, o seguinte trabalho podem:

c1=`echo -en '\01'`
c2=`echo -en '\02'`
cat logfile | tr '\n' $c1 | sed "s/$c1    /$c2/g" | sed "s/$c1/\n/g" | grep cat | sed "s/$c2/\n    /g"

Explicação: este substitui cada nova linha com ASCII 1 (um caractere de controle que nunca deveria aparecer em um arquivo de log) e cada seqüência de "nova linha-espaço-espaço-espaço-space" com ASCII 2 (outro caractere de controle). Em seguida, re-substitui ASCII 1 com novas linhas, então agora cada seqüência de várias linhas é colocado em uma linha, com os antigos quebras de linha substituídos por ASCII 2. Isto é grepped para o gato, e, em seguida, o ASCII 2 de são re-substituído pelo combinação nova linha-espaço-espaço-espaço-espaço.

Algo como isso?

awk 'function print_part() { if(cat) print part }  /^  / { part = part "\n" $0; next } /cat[0-9]$/ { print_part(); part = $0; cat = 1; next;  } { print_part(); cat=0} END { print_part() }' inputfile

Os /^ / linhas identifica expressões regulares de continuação.

Os identifica /cat[0-9]$/ regexp as linhas iniciais que você deseja manter.

Outra abordagem seria a criação RS ser algo diferente do \n normal. Por exemplo:

$ awk -v Pre=Wed 'BEGIN {RS = "\\n?\\s*" Pre} /cat.\n?/ {print Pre $0}' file.log
Wed Nov 12 blah blah blah blah cat1
Wed Nov 12 blah blah blah blah cat2
     more blah blah
     even more blah blah
Wed Nov 12 blah blah blah blah cat3
Wed Nov 12 blah blah blah blah cat4
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top