tail -f, mas com números de linha

19

Estou tentando ver quantas vezes foo bar aparece em /var/log/foo.log dentro de um período de tempo arbitrário em um servidor remoto, mas nada do que tentei até agora funcionou.

Já tenho um script de cronômetro que uso para saber quanto tempo passou desde que comecei a usar /var/log/foo.log e agora gostaria de saber quantas vezes foo bar apareceu na saída de cauda.

Eu pesquisei no google, mas não encontrei nada pertinente nas primeiras 10 páginas de resultados.

Veja o que tentei com resultados frustrantes:

## works on local machine, but doesn't work as expected on remote
tail -f /var/log/foo.log | grep foo\ bar | sed '='

## works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | cat -n -

##  works on local, but not remote
tail -f /var/log/foo.log | grep foo\ bar | awk -F'\n' '{printf "[%d]> ", NR; print $1}'

Eu até tentei escrever um script sed que funcionasse como tail -f , mas fiz um progresso limitado a nenhum com isso.

OBSERVAÇÃO

o servidor remoto está executando uma versão mais antiga do coreutils, e a atualização é uma opção, mas NÃO é a solução desejada.

    
por Alexej Magura 17.01.2014 / 23:15

7 respostas

25
tail -f | nl

funciona para mim e é o primeiro que eu pensei - ou seja, se você realmente quer as linhas numeradas de 1 e não com o número real da linha do arquivo assistido. Opcionalmente, adicione grep , se necessário, ao local apropriado (antes ou depois de nl ). No entanto, lembre-se que o buffer pode ocorrer. No meu caso particular, grep tem a opção --line-buffered , mas nl buffers é a saída e não tem uma opção para desativá-la. Portanto, a combinação tail | nl | grep não flui muito bem.

Dito isto,

tail -f | grep -n pattern

funciona para mim também. Numeração começa novamente desde o início do "tailing" em vez de início de todo o arquivo de log.

    
por 18.01.2014 / 00:39
11

Eu acho que isso é melhor ..

less -N +F <filepath>
    
por 24.04.2015 / 05:07
6

Você também pode enviar a saída para less , ela tem um recurso de número de linha, -N , o que permitiria que você percorresse o log.

$ tail -f /var/log/foo.log | less -N

Exemplo

  1 Jan 17 22:11:58 greeneggs fprintd[4323]: ** Message: entering main loop
  2 Jan 17 22:12:01 greeneggs su: (to root) saml on pts/5
  3 Jan 17 22:12:28 greeneggs fprintd[4323]: ** Message: No devices in use, exit
  4 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Git | personal_repo | Checking for remote changes...
  5 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git rev-parse HEAD
  6 Jan 17 22:12:56 greeneggs gnome-session[1876]: 22:12:56 | Cmd | personal_repo | git ls-remote --heads --exit-code "ssh://[email protected]      
  6 8us.org/home/sam/SparkleShare/personal_repo.git" master
  7 Jan 17 22:12:58 greeneggs gnome-session[1876]: X11 forwarding request failed on channel 1
  8 Jan 17 22:12:58 greeneggs gnome-session[1876]: 22:12:58 | Git | personal_repo | No remote changes, local+remote: 532213be48cce3b93cb177d409faa      
  8 03b71d0cfa5
  9 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Pinging tcp://notifications.sparkleshare.org:443/
 10 Jan 17 22:13:35 greeneggs gnome-session[1876]: 22:13:35 | ListenerTcp | Received pong from tcp://notifications.sparkleshare.org:443/

OBSERVAÇÃO: Observe a saída. Você pode ou não gostar desse recurso, mas ele precisará de linhas longas e cortá-las para que elas continuem na próxima linha, mas ainda mantenham o mesmo número de linha correspondente. Eu acho este recurso inestimável ao analisar arquivos de log que são largos! Você pode ver o efeito desse recurso nas linhas 6 & 8 .

    
por 18.01.2014 / 04:16
1

Para grep novas linhas apenas no arquivo de log como elas vêm com o número da linha, você poderia fazer:

{
  initial_lines=$(wc -l)
  tail -n +1 -f | awk -v NR="$initial_lines" '/pattern/{print NR": "$0}'
} < file.log

(com mawk , você vai querer adicionar a opção -Winteractive para evitar seu buffer de entrada (!)).

wc -l lê as linhas que já estavam lá e as conta (os caracteres de nova linha, o que significa que ainda funciona mesmo se a última linha ainda não estiver cheia), e então tail -f resto (a partir de onde wc parou de ler) e diga awk qual é o número da linha do primeiro que vê.

    
por 21.11.2017 / 18:36
0

Se você quisesse contar desde o início, precisaria que grep -n fosse aplicado a todas as linhas.

 tail -f -n100000000 filename.log | grep -n '' 

Se, em seguida, você quisesse mostrar apenas os 10 últimos, eu pensaria que você poderia refazer o processo:

 tail -f -n100000000 filename.log | grep -n '' | tail -n10

O primeiro é útil, mas mostra muita saída. Eu não sei porque o segundo não funciona.

    
por 21.11.2017 / 18:18
0

É o argumento n ou --lines (usado de maneiras ligeiramente diferentes, veja abaixo):

$ tail -f -n 25 /path/to/file.txt

$ tail -f --lines=25 /path/to/file.txt

Veja também a ajuda:

$ tail --help
    
por 31.05.2018 / 12:14
-1

O comando cat -n [filename] | tail receberá uma contagem rápida e exibirá os registros mais recentes, se é isso que você está procurando.

A opção -f torna-a persistente até a fuga - o que realmente não parece aplicável no seu cenário ou é redundante.

wc -l [filename] receberá uma contagem das linhas no destino

wc -l [filenameprefix]* contará todas as linhas em todos os arquivos correspondentes ao padrão e até relatará um total de resumos no final.

Detalhes mais completos podem gerar respostas mais completas.

    
por 02.07.2015 / 20:39