Contar o número de linhas de saída do programa anterior

Estou tentando contar o número de linhas de saída que um determinado programa produz. O problema é que o programa leva muito tempo para ser executado e eu quero exibir a saída para o usuário. Existe uma maneira de contar o número de linhas do último comando emitido?

Eu poderia fazer program | wc -l, mas isso não mostraria a saída para o usuário. Pelo que sei, tenho que fazer program; program | wc -l – mas o programa leva pelo menos um minuto para ser executado, então não quero ter que fazer mais de uma vez, apenas para mostrar uma contagem de linha na parte inferior.

EDITAR:

  • Existe uma maneira de mostrar a saída conforme ela acontece (linha por linha) e depois retornar uma contagem no final?

Comentários

  • Que tal: faça com que o programa acompanhe sua própria saída e apenas leia o valor da variável (por exemplo STDOUT_WRITE_COUNT), ou registre-o em um arquivo / API, no final do programa. WDYT?

Resposta

Você pode usar tee para dividir o fluxo de saída enviando uma cópia para wc e a outra cópia para STDOUT normalmente.

program | tee >(wc -l) 

A >(cmd) é a sintaxe bash, que significa ru n cmd e substitua o bit >(cmd) pelo caminho para (um canal nomeado conectado a) STDIN desse programa.

Comentários

  • >(cmd) é ksh sintaxe também reconhecida por zsh e bash e está usando apenas pipes nomeados em sistemas que não ' t tem /dev/fd/n.
  • @StephaneChazelas Sim, a maioria dos shells é compatível, mas ' não está em POSIX, para que ' não seja confiável para estar em todos os lugares.
  • Sim, eu estava apenas apontando que a substituição do processo não era uma bash invenção como o texto em sua resposta poderia fazer alguém acreditar.
  • @TheLibbster Depende de como você define eficiente. Este método envolve a geração de 2 processos adicionais, onde sed e awk são apenas um. Mas tee e wc são extremamente pequenos (muito menores do que sed e awk).
  • @TheLibbster sim, de acordo com alguns testes simples que acabei de fazer, ' é duas vezes mais rápido como os métodos sed e awk. (I dd d 100mb de /dev/urandom para um arquivo e, em seguida, executei esse arquivo em cada método várias vezes)

Resposta

Uma opção é usar awk, que pode fazer a contagem e imprimir em stdout.

program | awk "{ print } END { print NR }" 

Em awk, NR é o número da linha atual. Você pode fazer o mesmo com perl:

program | perl -pe "END {print "$.\n"}" 

Ou sed:

program | sed -n "p;$=" 

Comentários

  • Existe uma maneira de mostrar a saída conforme ela acontece (linha por linha) e, em seguida, retornar uma contagem no final ?

Resposta

minha opção favorita:

program | grep "" -c 

Comentários

  • OP pode ter perguntado outra coisa, mas vim aqui procurando apenas obter uma contagem do número de linhas de saída e não ' não se preocupe em mostrar a saída real, e isso faz o trabalho. Obrigado!

Resposta

Você pode clonar stdout em stderr.

program | tee /dev/stderr | wc -l 

Dessa forma, program” s stdout é canalizado para tee para ser escrito em stderr, que é impresso no console. tee também grava os dados canalizados para ele em seu stdout, que é canalizado para wc.

Resposta

Isso pode ser tarde. Mas gostaria apenas de responder à sua pergunta de acompanhamento sobre como capturar o número contado em uma variável.

Isso é o que você deseja YOUR_VAR=$(PROGRAM | tee /dev/stderr | wc -l).

Aproveitamos tee para gerar dois fluxos aqui e direcione um para /dev/stderr, que apareceria em sua tela, e o outro para wc -l, que relataria o número de linhas.

Resposta

tail -f /var/log/squid/access.log | ( c=0; pl() { echo $c; c=0; }; trap pl SIGHUP; while read a; do (( c=c+1 )); done ) & ( trap "kill $! ; exit" SIGINT; trap "" SIGHUP; while true; do kill -HUP $! ; sleep 1; done) 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *