Arquivo Cat para o terminal a uma velocidade específica de linhas por segundo

Arquivo Cat para o terminal a uma velocidade específica de linhas por segundo

Sou preguiçoso e poderia escrever um script para fazer isso, mas tenho preguiça até de pensar em como fazer.

Costumo fazer coisas como:

cris$ python runexperiment.py > output.txt
cris$ cat output.txt

Às vezes, ao observar o longo resultado de um experimento, gosto de deixar a página rolar e observar os padrões sucessivos se formarem e se dispersarem. Mas usar cat em um arquivo com 1 milhão de linhas termina em talvez 5 segundos. Isso é muito rápido até para mim.

Existe alguma maneira de diminuir a velocidade de visualização do arquivo, algo como um 'utilitário de rolagem'? Eu quero rápido, mas não 200 mil linhas por segundo (todas as quais, presumivelmente, a tela nunca seria registrada de qualquer maneira).

Algo como

cris$ scroll -lps=300 output.txt

E então sentar e assistir 300 linhas por segundo seria o ideal, eu imagino.

Responder1

Curto elegível:

perl -pe "system 'sleep .003'" log.txt

Posto essas soluções porque são pequenas e legíveis, conforme comentários deResposta do DMasparece promover esse tipo de solução!

Mas eu odeio isso porque: Para esta execução, perl irágarfopara /bin/sleep300x/segundos!

Este é um grande consumidor de recursos! Também um erroboas soluções!!

Usandoconstruídas emdormir

Infelizmente, o builtin sleepé limitado a números inteiros. Então, temos que usar select:

perl -e 'print && select undef,undef,undef,.00333 while <>;'

Em perl, print while <>pode ser substituído pela -popção:

perl -pe 'select undef,undef,undef,.00333'

Vamos tentar:

time /bin/ls -l /usr/bin | perl -pe 'select undef,undef,undef,.00333' | wc
   2667   24902  171131

real    0m9.173s
user    0m0.056s
sys     0m0.048s

bc -l < <(echo 2667/9.173)
290.74457647443584432573

Explicação:

  • 300 linhas/s significa 1 linha por 0,0033333333 segundos.

  • printsem argumento imprime $_o que éespaço de entrada padrão.

  • chamada como ... | perl -e, ... | perl -neou ... | perl -pe, a entrada padrão seria atribuída automaticamente à *STDINqual édescritor de arquivo padrão, então <>faria o mesmo <STDIN>que lerá a entrada padrão até $/(separador de registro de entradaque é por padrão umnova linha) será alcançado. Em inglês, por padrão <>será lidoumlinha da entrada padrão e atribuir conteúdo à $_variável.

  • &&é umecondição, mas é usado lá como umseparador de comando de cadeiaentão depois (com sucesso) imprima uma linha, executando o próximo comando.

  • selecté umtruque do programador para não usarsleep. Este comando foi projetado para interceptar eventos emdescritores de arquivo(entradas e/ou saídas, arquivos, soquete e/ou soquetes de rede). Com este comando, um programa poderiaesperepara 3 tipos de eventos,feed pronto para ler,feed pronto para escreverealgum evento aconteceu no feed. O quarto argumento é um tempo limite em segundos, então a sintaxe é select <feeds where wait for input>, <feeds where having to write>, <feed where something could happen>, <timeout>.

Para maior precisão, você poderia usar Time::Hireso módulo perl:

perl -MTime::HiRes -pe 'BEGIN{$start=Time::HiRes::time;$sleepPerLine=1/300};select undef,undef,undef,($start + $sleepPerLine*$. - Time::HiRes::time)'

Nota: $.énúmero da linha de entrada atual.

Melhor escrito comocat >catLps.pl

#!/usr/bin/perl -w

use strict;
use Time::HiRes qw|time|;

my $start=time;
my $lps=300;

$lps=shift @ARGV if @ARGV && $ARGV[0]=~/^(\d+)$/;
my $sleepPerLine=1/$lps;

print &&
    select undef,undef,undef,($start + $sleepPerLine*$. - Time::HiRes::time)
    while <>

Uso:

catLps.pl [lps] [file] [file]...

Primeiro argumentolpsé um argumento numérico opcional de linha por segundos (padrão: 300)

Nota: se o nome do arquivo for apenas numérico, talvez seja necessário especificá-lo com path: ./3.

Assim catpoderia passar arquivos dados como argumento e/ouentrada padrão

Então poderíamos:

TIMEFORMAT='%R' 
time seq 1 100 | ./catLps.pl 100 >/dev/null 
1.040

time seq 1 10000 | ./catLps.pl 10000 >/dev/null  
1.042

Para se divertir:

export TIMEFORMAT='%R' ;clear ;time seq 1 $((LINES-2)) | ./catLps.pl $((LINES-2))

Responder2

basta usar awk com sleep:

awk '{print $0; system("sleep .1");}' log.txt

Responder3

Em vez de usar um intérprete, você pode usar uma ferramenta feita especificamente. Provavelmente está instalado na sua distribuição ou você pode instalá-lo (apt-get install pv, etc.)

Para exibir o arquivo a 5 linhas por segundo:

cat filename | pv --quiet --line-mode --rate-limit 5

Para exibir o arquivo a 100 bytes por segundo:

cat filename| pv --quiet  --rate-limit 100

Responder4

A função do Ruby sleepsuporta valores de ponto flutuante, então aqui está uma solução eficiente e curta baseada na resposta de @F.Hauri:

ruby -pe 'sleep 0.00333' log.txt

ou

ruby -pe 'sleep (1.0/300)' log.txt

informação relacionada