Grep última correspondência do arquivo

1

Estou executando o seguinte comando em um arquivo de log e desejando apenas a última / última correspondência. Às vezes, pode haver apenas uma correspondência, outras vezes pode haver várias, o que está causando um problema para mim, já que o comando a seguir está retornando as duas correspondências:

cat "$(ls -t | head -n1)" | grep -P "(NODE1[\s\S]*TEST\s=\sPOWER[\s\S]*OUTPUT\s=\s\d+?.*\s+;?)"

>>>>> (results in)...

NODE1 2018-03-06 12:01:23
  TEST = POWER
  EVENT_TIME = 2018-03-06 12:01:23
  OUTPUT = 12

;

NODE1 2018-03-06 12:03:23
  TEST = POWER
  EVENT_TIME = 2018-03-06 12:03:23
  OUTPUT = 7

;

Eu preciso do último grupo correspondente no evento, há vários. Isso é possível com grep / regex ou eu preciso canalizar os resultados em sed / awk? Se sim, como?

    
por Godzilla74 06.03.2018 / 21:55

3 respostas

0

Eu proponho a você esta solução:

cat <your_source_file> | sed -n '/NODE1/,/;/p' | tr '\n' '|' | awk -F ';' '{print $(NF-1)}'|tr '|' '\n'

sed -n '/NODE1/,/;/p' - encontre blocos "NODE1".

tr '\n' '|' converte novas linhas para o separador de registros, portanto, as colunas da tabela serão separadas por ';'.

awk -F ';' '{print $(NF-1)}' - imprime a última coluna da tabela.

tr '|' '\n' - recuando para a visualização anterior para registro.

awk -F ';' '{for(i=(NF-1); i>0; i--){ if($i ~ "TEST = POWER"){print $i} } }' - apenas eventos "TEST = POWER".

    
por 06.03.2018 / 23:29
2

Com base na sugestão de Yurij, comecei a investigar usando tac em vez de cat e invertendo minha declaração grep . Agora, estou vendo o arquivo de baixo para cima e pegando o primeiro jogo:

tac "$(ls -t | head -n1)" | grep -m 1 -P "\d+[\s\S]*TEST\s=\sTXPOWER" | tac

    
por 06.03.2018 / 23:27
0

Acho o perl mais conveniente para isso:

perl -lane 'if(/^NODE1 /&&($#n=-1)../^;$/){push @n,$_} END{print $_ for @n}' file

Explicação:

perl Linguagem de extração e relatórios práticos.
-lane normalmente é útil para one-liners.
' do início das instruções do programa real
if(/^NODE1 /&&($#n=-1)../^;$/) considera apenas partes do texto começando com uma linha stat começa com NODE1 seguido por um espaço em branco e termina com uma linha contendo um ponto-e-vírgula único. /^NODE1 /&&($#n=-1) redefiniu a matriz @n no início da parte do texto.
{push @n,$_} salve cada linha na parte de texto como um elemento de uma matriz chamada @n
END{print $_ for @n} quando o arquivo inteiro foi analisado, imprima a parte de texto salva em @n .
' end das instruções do programa.
file , este é um espaço reservado para o nome do arquivo que você deseja processar.

    
por 18.04.2018 / 12:55