
Eu tenho um arquivo de log que contém o seguinte conteúdo.
2021-06-15T22:50:11+00:00 DEBUG {"slug": "something", "key2": "value2"}
Gostaria de enviar tail -f
este arquivo e canalizar os resultados para jq
o comando, mas preciso retirar 2021-06-15T22:50:11+00:00 DEBUG
parte antes de canalizar, jq
pois jq
espera uma string JSON.
Existe uma maneira de acompanhar o arquivo de log e remover a parte de data e hora ao mesmo tempo?
Por fim, gostaria de usar o seguinte comando.
tail -f :file | jq
Responder1
Supondo que você tenha acesso ao GNU, sed
que é capaz de produzir saída sem buffer:
tail -f file | sed -u 's/^[^{]*//' | jq .
Isso seria executado tail -f
no seu arquivo e enviaria continuamente novos dados para o arquivo sed
. O sed
comando retiraria tudo até o espaço antes do primeiro {
da linha e depois enviaria o resultado para jq
.
A -u
opção para GNU sed
faz com que ele não armazene em buffer a saída. Sem esta opção, sed
o resultado seria armazenado em buffer e só enviaria os dados jq
quando o buffer (4 Kb?) estivesse cheio. Fazer buffer assim é um procedimento padrão quando a saída de uma ferramenta não é o próprio terminal, e isso é feito por razões de eficiência. Nesse caso, podemos querer desativar o buffer, então usamos -u
.
Para selecionar apenas linhas que contenham a DEBUG
string antes dos dados JSON:
tail -f file | sed -u -e '/^[^{]*DEBUG /!d' -e 's///' | jq .
ou
tail -f file | sed -u -n 's/^[^{]*DEBUG //p' | jq .
O sed
comando aqui excluiria todas as linhas que não iniciam com algum texto que não contenha {
caracteres, terminando em DEBUG
. Se tal linha for encontrada, o texto correspondente será removido, deixando os dados JSON.
Observe que aqui extraímos o JSON com base na DEBUG
string, e não na {
que inicia um objeto JSON.
Relacionado ao buffer em pipelines:
Responder2
Para remover as duas primeiras colunas delimitadas por espaço:
tail -f file | stdbuf -oL cut -d ' ' -f3- | jq .
( stdbuf -oL
, conforme encontrado em sistemas GNU ou FreeBSD, truques cut
para fazer buffer de saída baseado em linha em vez de baseado em bloco).