Estou escrevendo um script ksh para analisar um arquivo de log e enviar um e-mail quando forem encontradas mensagens importantes. Algumas mensagens são informativas e gostaria de ignorá-las.
O arquivo de log tem formato
2018-01-24.08.24.35.875675 some text
more text
more text
more text
more text
2018-01-24.08.24.37.164538 some text
more text
more text
INF9999W <-- informational text
more text
2018-01-24.08.24.46.8602545 some text
more text
more text
more text
O timestamp seria considerado o separador da mensagem, sendo o timestamp pertencente à mensagem que o segue. Eu gostaria de pesquisar o arquivo para cada ocorrência de "texto de informação" e, em seguida, remover toda a mensagem do arquivo (do carimbo de data / hora anterior até pouco antes do próximo carimbo de data / hora).
Como posso determinar facilmente os números de linha dos timestamps anteriores e seguintes para remover essas linhas com:
awk 'NR<'$preceding_ts' || NR >='$following_ts'
Minha maneira é colocar todas as linhas de carimbo de data/hora em um arquivo e, em seguida, percorrer esse arquivo até encontrar as linhas de carimbo de data/hora que estão logo antes e depois da linha # de 'texto de informação'. Parece muito trabalho, especialmente em um arquivo grande. Existe uma maneira mais eficiente.
integer inf_line
integer last_ts_line
integer cur_ts
cp $error_log $copy_log
while true
do
inf_line=$(grep -n "INF99999W" $copy_log | head -1 | cut -f1 -d":")
if [[ $inf_line -eq 0 ]]
then
break
fi
grep -n -E "^20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]-" $copy_log | cut -f1 -d":" > $ts_lines
last_ts_line=99999999
cat $ts_lines | while read cur_ts
do
if [[ $cur_ts -gt $inf_line && $last_ts_line -lt $inf_line ]]
then
awk 'NR<'$last_ts_line' || NR >='$cur_ts'' $copy_log > $temp_log
cp $temp_log $copy_log
last_ts_line=$cur_ts
break
fi
last_ts_line=$cur_ts
done
if [[ $last_ts_line -lt $inf_line ]]
then
awk 'NR<'$last_ts_line'' $copy_log > $temp_log
cp $temp_log $copy_log
fi
done
Obrigado.