Arquivo Cat para terminal em velocidade específica de linhas por segundo

11

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

Costumo fazer coisas como:

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

Às vezes, quando observamos a saída longa de um experimento, eu gosto de deixar a página apenas rolar e ver os padrões sucessivos se formando e se dispersando. Mas usando cat em um arquivo com 1 milhão de linhas termina em talvez 5 segundos. Isso é muito rápido mesmo 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).

Algo como

cris$ scroll -lps=300 output.txt

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

    
por Cris Stringfellow 31.12.2012 / 08:31

3 respostas

11

Existem vários utilitários que permitem especificar uma taxa, como pv , mas é a taxa em bytes por segundo, não linhas por segundo.

Mas se você realmente quiser usar o lps, você pode fazer isso:

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

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

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 / seg. 1 linha por 0,0033333333 seg.

  • print sem argumento imprime $_ , que é espaço de entrada padrão .

  • chamado como ... | perl -e , ... | perl -ne ou ... | perl -pe , a entrada padrão seria atribuída automaticamente a *STDIN , que é descritor de arquivo padrão , portanto, <> faria o o mesmo que <STDIN> , que lerá da entrada padrão até que $/ ( registro de registro , que é por padrão uma nova linha ) seja alcançado. Em inglês, por padrão, <> lerá a linha um da entrada padrão e atribuirá o conteúdo à variável $_ .

  • && é uma condição e , mas é usado como um separador de comando de cadeia , assim após (com êxito) imprimir uma linha, executando o próximo comando.

  • select é um truque do programador para não usar sleep . Este comando é projetado para interceptar eventos em descritores de arquivos (entradas e / ou saídas, arquivos, soquetes e / ou soquetes de rede). Com este comando, um programa poderia esperar por 3 tipos de eventos, feed pronto para ler , feed pronto para gravar e algum evento aconteceu no feed . O quarto argumento é um tempo limite em segundos, portanto, a sintaxe é select <feeds where wait for input>, <feeds where having to write>, <feed where something could happen>, <timeout> .

Para mais precisão, você pode usar o módulo Time::Hires 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 como cat >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]...

First argument lps is optional line per seconds numeric argument (default: 300)

Note: if filename is only numeric, you may have to specifiy them with path: ./3.

Like cat this could pass files given as argument and/or standard input

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 diversão:

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

apenas use o awk com o sono:

awk '{print $0; system("sleep .1");}' log.txt
    
por 04.01.2018 / 15:26
-1

Estou atrasado para a festa, mas achei que seria um exercício de aprendizado útil para experimentar em python, então vou colocar o que tenho:

#!/usr/bin/env python3

import argparse
from time import sleep

parser = argparse.ArgumentParser(description='Echo a file slowly')
parser.add_argument('-i',
                    '--input-file',
                    type=argparse.FileType('r'),
                    default='-')
parser.add_argument('-d',
                    '--delay-in-ms',
                    type=int,
                    default='100')
args = parser.parse_args()

for line in args.input_file:
    print(line.rstrip())
    sleep(args.delay_in_ms/1000.0)

Aceita entrada de stdin ou como um argumento (-i) e por padrão escreve uma linha por 1 / 10th de segundo, mas isso pode ser alterado com outro argumento (-d).

    
por 11.08.2017 / 15:12