Como eu procuro por certas seções de um arquivo e depois extraio somente informações relevantes dentro daquela seção?

1

Eu tenho um arquivo de texto que é um relatório do servidor que tem cerca de 1000 linhas de informação nele. Estou tentando escrever um script que possa pesquisar no relatório apenas algumas informações que estou procurando.

Por exemplo:

Server 1 Health Check

Date - Count of errors


06/25/15 : 14

6/24/15 : 21

6/23/15 : 17

6/24/15 : 33

Server 2 Health Check

Date - Count of errors


06/25/15 : 4

6/24/15 : 13

6/23/15 : 21

6/24/15 : 33

Errors caused by X


Server 1:

32

Server 2:

24

As três seções são

  • "Verificação de integridade do servidor 1",
  • "Verificação de integridade do servidor 2" e
  • "Erros causados por x".

Os dados de cada seção que eu preciso extrair estão em negrito.

Alguém sabe como eu poderia fazer isso?
Eu sei que posso usar grep , mas não posso usar grep com as sinalizações -A , -B e -C .

    
por Cpoole 25.06.2015 / 15:35

3 respostas

1

Que tal um script sed com gotos (shock, horror)? Isso poderia ser simplificado se você descreva seus dados com mais precisão.

sed -n '
:start
  /Server .* Health Check/{
      n
      /Date - Count/n
   :loop1
      / : /{p; n; b loop1
      }
      b start
  }
  /Errors caused by/{
      n
   :loop2
      /Server/n
      /^[0-9]/{p; n; b loop2
      }
      b start
  }
'

O script reconhece o primeiro estilo de cabeçalho e insere a parte {}. isto lê a próxima linha (n) e se for o cabeçalho Data, lê outra linha. Se a linha corresponder à linha de estilo ":" (/: /), ela entra na parte {} que imprime a linha (p), lê a próxima linha (n) e ramifica (b) para rotular loop1. Quando não houver mais linhas correspondentes, ela se ramifica para o início da etiqueta.

O mesmo acontece quando o segundo estilo de cabeçalho é visto.

    
por 25.06.2015 / 17:10
1

Bem, se você tem ferramentas GNU, pode fazer:

for match in \
    Server\ Health\ Check\ 1
    Server\ Health\ Check\ 2
    Errors\ caused\ by\ X
do  grep -Fxm1 "$match"
    case $match in 
    (S*) sed -nEu '/^[0-9/:]+/!q;p';;
    (*)  sed -u '4q;3d;1d';;
esac;done <file

A suposição aqui é que existem alguns dados intermediários entre as seções em que você está interessado (porque senão: cat ) .

Sem ferramentas GNU:

grep -nxE 'Server Health Check [12]|Errors caused by X' <file |
sed 's|\([^:]*\):S.*|,/\n.*[^0-9/:]/{!P?}?|
     s|\([^:]*\):E.*|{N;s/.*\n//p;N;s///p?}?|
     y/?/\n/' | sed -e1!N -f- -eD ./file
    
por 25.06.2015 / 15:47
0

Use uma linguagem de script completa, por exemplo Perl, Python ou Ruby de acordo com o que você está mais familiarizado. Se nenhum deles, provavelmente, o aprendizado do Python lhe dará mais retorno do investimento. Muitas distribuições Linux usam o Python para ferramentas e tarefas críticas do sistema que não sejam de desempenho, sabendo como ler as que serão pagas em algum dia.

Ser capaz de pesquisar, dissecar linhas e extrair informações e organizar os resultados em estruturas de dados capazes e flexíveis economizará trabalho nesse caso e em muitos outros similares a seguir.

    
por 26.10.2015 / 02:54