Saída do comando 'watch' como uma lista

27

Eu quero fazer um cálculo simples do número de linhas por minuto adicionado a um arquivo de log.

Também quero armazenar a contagem para cada segundo.

O que eu preciso é da saída do seguinte comando como uma lista que será atualizada a cada segundo:

watch -n1 'wc -l my.log'

Como gerar a 'atualização' do comando 'watch' como uma lista?

JohnJohnGa
fonte

Respostas:

24

Você pode usar a -topção watchque faz com que não imprima o cabeçalho. No entanto, isso ainda limpará a tela para que você possa se sair melhor com um simples loop de shell:

while sleep 1; do
    wc -l my.log
done

Uma das vantagens é que você pode adicionar facilmente outros comandos (por exemplo date) e / ou canalizar a saída sedpara reformatá-la. A propósito, se você trocar sleep 1com wcno loop, ele terminará automaticamente com erros.

peterph
fonte
No entanto nota que ele não vai fazê-lo exatamente a cada segundo (com zsh ou ksh93, você pode ajustar o tempo de sono, de modo a conta para a deriva incorridos, executando os comandos no circuito, embora)
Stéphane Chazelas
2
@StephaneChazelas também não vai wait- tente watch -n 1 "sleep 5".
Peterph
De fato (verifiquei as implementações procps e busybox). Eu pensei que essa era a única coisa watchútil, mas ela não fornece nem uma solução tão boa quanto uma baseada em relógio, mas nenhuma responde à pergunta "taxa na qual um arquivo de log cresce" com grande precisão.
Stéphane Chazelas
Bem, se as linhas por minuto são o objetivo final, então a amostragem a cada 10 segundos é mais do que suficiente - então a sobrecarga não é tão terrível (a menos que o arquivo cresça muito grande, é claro). E, na verdade, de dentro do loop, é possível imprimir informações de tempo (mesmo antes e depois do comando terminar, se necessário) e, em seguida, a precisão pode melhorar (ordens de magnitude), mesmo para arquivos maiores.
Peterph
11
O @peterph watchtem uma -popção que fará isso corretamente, se possível (obviamente, você não pode executar um comando que leva 5 segundos a cada 1 segundo, se não for permitido vários simultâneos). Eu sei, eu escrevi :-P
derobert
8

Uma pergunta antiga, mas acabei de encontrar uma resposta muito fácil:

watch -n1 'wc -l my.log | tee -a statistics.log'

Isso executará wccada segundo, adicionará sua saída ao arquivo Statistics.log e também a exibirá na tela.
Então, você terminará com um arquivo preenchido com números, representando o número sucessivo de linhas de my.log.

Orabîg
fonte
Por favor, note que este comando watch "($MYCMD | tee -a $MYLOG)"não é watch "($MYCMD)" | tee -a $MYLOG. Se você entendeu errado como eu, a saída será muito, muito confusa. Outra coisa a ser observada aqui é que esse comando não adiciona o registro de data e hora da execução de cada comando por padrão, portanto a resposta com o loop ainda pode funcionar melhor para você.
ffledgling
3

E se

tail -f file.log | pv -rl > /dev/null
Stéphane Chazelas
fonte
3

Tente o seguinte:

watch -n1 'wc -l my.log >> statistics.log'
Andy
fonte
1

Me deparei com essa pergunta quando estava tentando obter uma saída melhor / registrada du -sh $data_path. Eu usei o padrão "while command, sleep" encontrado aqui, mas usei um AWK complexo para dar a saída que eu queria.

while du -sh $data_path; do sleep 1; done | awk '
$1 != size {
    size=$1;
    path=$2;
    time=systime();
    seconds=time-prevtime;
    if(seconds < 1000000000){
        seconds=seconds" seconds"
    }else{
        seconds=""
    }
    print size, path, strftime("%m/%d/%Y@%H:%M:%S", time), seconds; 
    prevtime=time
}'

Na verdade, eu fiz isso como um oneliner, e é por isso que há ponto e vírgula. Mas, para torná-lo legível, eu o expliquei. A saída se parece com:

502G /var/lib/cassandra/dump/ 05/22/2018@04:46:17
503G /var/lib/cassandra/dump/ 05/22/2018@04:46:59 42 seconds
504G /var/lib/cassandra/dump/ 05/22/2018@04:47:57 58 seconds
505G /var/lib/cassandra/dump/ 05/22/2018@04:48:55 58 seconds
506G /var/lib/cassandra/dump/ 05/22/2018@04:49:53 58 seconds
507G /var/lib/cassandra/dump/ 05/22/2018@04:50:50 57 seconds
508G /var/lib/cassandra/dump/ 05/22/2018@04:51:46 56 seconds
509G /var/lib/cassandra/dump/ 05/22/2018@04:52:44 58 seconds
510G /var/lib/cassandra/dump/ 05/22/2018@04:53:41 57 seconds
Bruno Bronosky
fonte
0

Você pode criar um script que faça isso por você. Liguei para o meu keep(como, continue fazendo isso) e coloquei no bincaminho.

Este é o meu script:

#!/bin/bash
echo "Repeating command $* every second"
while sleep 1; do
    "$@"
done
Alexandre Santos
fonte
11
Você deve usar "$@"para executar o comando (argumentos) em vez de sem aspas $*. Dessa forma, você fará com que o shell mantenha argumentos citados, etc., como o usuário esperaria. FTFY.
0000 roaima #