Cat dosyası, saniyede belirli hat hızında terminale


15

Tembelim ve bunu yapmak için bir senaryo yazabilirim, ancak nasıl yapılacağını düşünmek için çok tembelim.

Sık sık şöyle şeyler yaparım:

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

Bazen bir denemenin uzun çıktısına bakarken, sayfanın art arda kalıplar oluşturup dağılmasına izin vermesini isterim. Ancak 1 milyon satırlı bir dosyada kedi kullanmak belki 5 saniyede bitiyor. Bu benim için bile çok hızlı.

'Kaydırma yardımcı programı' gibi bir dosyayı görüntüleme hızını yavaşlatmanın herhangi bir yolu var mı? Hızlı, ama saniyede 200 bin satır istemiyorum (muhtemelen ekran hiçbir şekilde kayıt bile yapmaz).

Gibi bir şey

cris$ scroll -lps=300 output.txt

Sonra arkanıza yaslanıp saniyede 300 satır geçmiş rulo izlemenin ideal olacağını düşünüyorum.


7
Gibi bir şey deneyin cat FILENAME | pv -l -L 900 -q. Sınır saniyede bayt değil, saniyede bayt cinsinden, bu yüzden bunu bir cevap değil bir yorum yapıyorum.
David Schwartz

Tamam, bu harika bir yardımcı program ve kısmen çalışıyor. Ama evet, biraz dalgalı çünkü bps'den sonra lps değil.
Cris Stringfellow

Yanıtlar:


17

Kısa ve okunabilir :

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

Bu çözümleri gönderiyorum , çünkü DMas'ın cevabının yorumları bu tür bir çözümü teşvik ediyor gibi küçük ve okunabilirler !

Bu çalışma için, perl olacaktır: Ama bu, çünkü nefret çatal için /bin/sleep300x / saniye!

Bu büyük kaynak kaynağı! Ayrıca yanlış iyi çözümler !!

yerleşik uyku kullanma

Ne yazık ki, yerleşik sleeptamsayılarla sınırlıdır. Bunun selectyerine şunu kullanmalıyız :

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

Perl altında print while <>, -panahtar ile değiştirilebilir :

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

Hadi deneyelim:

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

Açıklama:

  • 300 satır / sn, 1 satır 0.0033333333 saniye anlamına gelir.

  • printargüman baskılar olmadan $_hangi varsayılan giriş alanı .

  • olarak adlandırılan ... | perl -e, ... | perl -neveya ... | perl -pestandart girdi otomatik olarak tayin edileceğini, *STDINolduğu varsayılan dosya tanımlayıcı yüzden, <>aynı yapacağını <STDIN>kadar standart girdiden okuyacaktır hangi $/( giriş kayıt ayırıcı varsayılan olarak ise satır ulaşılacaktır). İngilizce olarak, varsayılan olarak standart girişten bir satır <>okuyacak ve değişkene içerik atayacaktır .$_

  • &&bir ve koşuludur, ancak burada bir zincir komut ayırıcısı olarak kullanılır, bu nedenle bir satır (başarıyla) yazdırdıktan sonra bir sonraki komutu yapar.

  • selectkullanmamak için bir programcının hilesisleep . Bu komut, dosya tanımlayıcılarındaki (girişler ve / veya çıkışlar, dosyalar, soket ve / veya ağ yuvaları) olayları yakalamak için tasarlanmıştır . Bu komutla, bir program 3 tür olayı bekleyebilir , beslemeye okumaya hazır , yem yazmaya hazır olabilir ve yemde bazı olaylar olabilir . Dördüncü argüman saniye cinsinden bir zaman aşımıdır, yani sözdizimi select <feeds where wait for input>, <feeds where having to write>, <feed where something could happen>, <timeout>.

Daha fazla hassasiyet için Time::Hiresperl modülünü kullanabilirsiniz :

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

Not: $.bir akım giriş hattı sayısı .

Olarak daha iyi yazılmış 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 <>

Kullanımı:

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

İlk bağımsız değişken lps, saniye başına isteğe bağlı satır sayısal bağımsız değişkenidir (varsayılan: 300)

Not: Dosya adı yalnızca sayısalsa, bunları path: ile belirtmeniz gerekebilir ./3.

Gibi catbu argüman ve / veya verilen dosyaları geçebileceği standart girdi

Böylece yapabiliriz:

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

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

Eğlence için:

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

2
orada ciddi bir vudu gibi görünüyor. çok havalı, denedim ve işe yarıyor. Bunu nasıl yaptığın hakkında hiçbir fikrim yok. perl ne seçiyor? undef? Ben bakabilirim. inanılmaz.
Cris Stringfellow

2
@CrisStringfellow Tamam, Time::HiResdaha fazla doğruluk için perl modülünü kullanarak bir açıklama ve tam komut dosyası
ekledim

Tanrım. Bu harika bir cevap. Teşekkür ederim. İkinci kez tekrar oylamaya çalıştım. Harika açıklamanızı okuyarak bir şeyler öğreniyorum.
Cris Stringfellow

2
Sen de benim yorumlarımı oy verebilir ;-)
F. Hauri

@CrisStringfellow Yanıt düzenlendi: -pperl komutuna geç komutuyla komut dosyası hafifletildi!
F.Hauri

11

awk ile uyku kullanın:

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

Bu benim için çalıştı ve durumum için yukarıdaki komut dosyası seçenekleri yerine en iyi seçenekti. Bu cevabın neden düşük oy kullanıldığından emin değilim.
Citizen Kepler

2
Perl çözeltisinin aksine oldukça okunabilir.
Gunslinger

1
@Gunslinger: Sözdizimi system(*sleep .1")10 çatal / saniye üretecek! Bu yazılabilir perl -pe 'system "sleep .1"' log.txt: Çok okunabilir, ama çok pahalı (sistem dostu değil!)
F. Hauri

Ben de bu okunabilir cevabı tercih ediyorum. Tek şey, çıkardığı her satır için kabuk uyku komutunu tetikleyecek olmasıdır. Ama mükemmel okunabilir bir astar olmak umrumda değil.
itsafire

0

Partiye geç kaldım, ama bunun python'da denemek için yararlı bir öğrenme egzersizi olacağını buldum, bu yüzden sahip olduğum şeyi koyacağım:

#!/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)

Stdin'den veya argüman (-i) olarak girişi kabul eder ve varsayılan olarak saniyenin 1 / 10'u başına bir satır yazar, ancak bu başka bir argümanla (-d) değiştirilebilir.


Teşekkürler. Bu soru-cevap üzerine Python'da bu fikre benzer bir şey geliştirmeye başladım. Python'un , F. Hauri'nin cevabında kullanıldığı gibi Perl'e benzer şekilde belirli docs.python.org/3/library/select.html dosyasını desteklediğini de not ediyorum .
ybull
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.