If Else, Awk NR: Como remover um cabeçalho de seção da tabela onde não há entradas

4

Estou tentando resumir uma tabela de dados que muda todos os dias. Já sumarizei a tabela para exibir apenas linhas com entradas maiores que 30.

No entanto, em alguns dias, não há entradas acima de 30 na tabela original. Quando isso acontece, não preciso de toda a seção vazia no resumo. Como faço para remover todo o cabeçalho dessas seções?

Idealmente, se não houver entradas em todas as 5 seções, não deverá haver nenhuma linha impressa (ou apenas uma string que diga: "Nenhuma: não há entrada maior que 30" como eu estava tentando fazer)

Exemplo de uma tabela resumida com 5 seções, summarised_output.txt:

=========================================================================================================
Month: Jun      

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun     

Counter Name                                06/05 14:00     06/05 13:00     06/05 12:00     06/05 11:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun      

Counter Name                                06/05 10:00     06/05 09:00     06/05 08:00     06/05 07:00
=========================================================================================================


=========================================================================================================
Month: Jun    

Counter Name                                06/05 06:00     06/05 05:00     06/05 04:00     06/05 03:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun      

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================

Como você pode ver, a terceira seção está vazia porque não há entrada no arquivo original_output.txt maior que 30. Mas o cabeçalho ainda está lá.

Meu código de resumo (trabalhado):

awk '$1=="Month:"||$1==""||$1=="Counter"||(index($1, "=")!=0)||$3>=30|| $4>=30 || $5>=30||$6>=30' original_output.txt>>summarised_output.txt

Minha tentativa de excluir o cabeçalho (não funciona):

touch summarised_output_temp.txt
awk '{if ($1=="Month:"||$1==""||$1=="Counter"||(index($1, "=")!=0)||$3>=30|| $4>=30 || $5>=30||$6>=30) print $0}' original_output.txt >> summarised_output_temp.txt
if (((wc -l < summarised_output_temp.txt)==42))
then
echo "None: there is no entry larger than 30" >> summarised_output.txt
else
cat output_7_temp.txt>>summarised_output.txt
fi

O erro recebido pela tentativa:

line 3: ((: (wc -l output_7_temp.txt | awk {print $1})==42: syntax error: invalid arithmetic operator (error token is ".txt | awk {print $1})==42")
    
por tthhss 05.06.2018 / 10:30

4 respostas

1

Contanto que você tenha o GNU awk , você pode usar este script:

awk -v RS='={105}[^=]*={105}' 'NF{print oRT,$0} {oRT=RT}' file

O cabeçalho da tabela é definido como um separador de registro de várias linhas RS . É composto de duas vezes 105 = caracteres com qualquer coisa entre eles.

A variável RT está capturando o registro separtor de cada registro e é armazenada na variável oRT e impressa no próximo registro, desde que haja alguns elementos para imprimir (o que é obtido com NF ).

    
por 05.06.2018 / 11:07
1

Crie um script executável test.awk, contendo

awk '
  # { print "read " $0 }
  /^SYS/ {
    if (H) {
      if (F) {print F} else { F="\r\n\r\n"}
      print H; H=""}
    print
    next
  }
  /^./ {
    H=$0
    for (i=1; i<5; i++) {
      getline
      H = H "\r\n" $0
    }
    next
  }
' $@

e execute

test.awk original_output.txt

"/ ^ SYS / {" pode ser substituído por qualquer coisa que reconheça uma linha de dados.

    
por 05.06.2018 / 12:16
1

Esse problema pode ser resolvido com Perl ao longo destas linhas.

Código

perl -F'/^=+$/m' -lan -0777e '
   my($dashes) = /^(=+)$/m;
   shift @F; pop @F;
   while ( @F > 1 ) {
      my($h, $s) = splice @F, 0, 2;
      next if $s =~ /^(?:\h*\n)+$/;
      print join $dashes, q(), $h, $s, !@F ? q() : ();
   }
' input.txt

Resultado

=========================================================================================================
Month: Jun

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/05 14:00     06/05 13:00     06/05 12:00     06/05 11:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/05 06:00     06/05 05:00     06/05 04:00     06/05 03:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================

Explicação

  • Slurp a entrada de uma só vez: a opção -0777 para Perl ativa isso.
  • Divida esse arquivo inteiro (agora sendo tratado como uma string longa) ao longo dos traços: / ^ = + $ / m significa que uma determinada linha não contém nada, mas repetidos iguais é onde dividimos o arquivo em.
  • A opção -a fará com que perl coloque as partes divididas no array @F .
  • A opção -n para Perl desabilitará o autoprinting antes de ler o próximo registro E também fará um loop parecido com awk em registros lidos da entrada.
  • Primeiro, armazenamos a linha dos traços da entrada.
  • Observe que a operação de divisão fará com que o primeiro e o último elementos fiquem vazios, portanto, removemos os da matriz @F antes de executar a tarefa principal.
  • Configuramos um loop while que consome 2 elementos ( splice ) por vez da matriz @F . O primeiro é o cabeçalho e o segundo a seção. O loop continua enquanto houver pelo menos dois elementos ainda no array.
  • O ponto-chave é tomar a decisão de pular ou não pular o processamento do cabeçalho / seção duo. E isso é decidido quando a seção compreende apenas linhas vazias ou linhas que compreendem apenas espaço em branco horizontal ( \ h ). O regex para isso é / ^ (?: \ H * \ n) + $ /
  • Agora, se a seção não estiver vazia, resta a tarefa de unir o cabeçalho / seção com os traços. Temos em mente que no último cabeçalho / seção se juntando precisamos adicionar os traços para arredondar.
por 05.06.2018 / 14:56
1

Semelhante à resposta de oliv, talvez um pouco mais simples:

gawk -v RS='=+\n' '
    NR % 2 == 0 {header = $0; next}
    /[^[:space:]]/ {printf "%s", RT header RT $0}
    END {print RT}
' output.txt 

Usando uma linha de = s como o separador de registro. O cabeçalho é, então, todo registro com numeração par. E o "conteúdo" não está vazio se contiver um caractere que não seja espaço em branco.

RT é uma variável específica do GNU awk que contém "O texto de entrada que corresponde ao texto denotado por RS, o separador de registro. Ele é definido toda vez que um registro é lido."

    
por 05.06.2018 / 15:38