1秒あたりの特定の回線速度で端末へのCatファイル


15

私は怠け者で、これを行うためのスクリプトを書くこともできますが、それを行う方法を考えるにはあまりにも面倒です。

私はしばしば次のようなことをします:

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

実験の長い出力を見るとき、ページをスクロールさせて、連続するパターンが形成されて分散するのを見てみたいことがあります。しかし、100万行のファイルでcatを使用すると、5秒で終了します。これは私にとっても速すぎます。

「スクロールユーティリティ」など、ファイルの表示速度を遅くする方法はありますか?速くしたいのですが、1秒あたり20万行ではありません(そのすべては、とにかく登録されないでしょう)。

何かのようなもの

cris$ scroll -lps=300 output.txt

そして、座って毎秒300行をロールバックするのが理想的だと思います。


7
のようなものを試してくださいcat FILENAME | pv -l -L 900 -q。制限は1秒あたりの行数ではなく、1秒あたりのバイト数であるため、これを回答ではなくコメントにします。
デビッドシュワルツ

わかりました。これは便利なユーティリティであり、部分的に機能します。しかし、はい、それはlpではなくbpsの後に行くため、少し不安定です。
クリスストリングフェロー

回答:


17

短くて読みやすい

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

DMasの答えのコメントがこの種のソリューションを促進しているように見えるので、私はこのソリューションを小さくて読みやすいので投稿します!

しかし、私はこれが嫌いです:この実行のために、perlは300x /秒に分岐/bin/sleepます!

これは大きな資源消費者です!また、間違った良い解決策 !!

組み込みスリープを使用する

幸いなことに、組み込みsleepは整数に制限されています。したがって、select代わりに使用する必要があります。

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

perlではprint while <>-pスイッチに置き換えることができます。

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

やってみよう:

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

説明:

  • 300行/秒は、0.0033333333秒で1行を意味します。

  • print引数のないprints $_デフォルトの入力スペースです。

  • またはと呼ばれる... | perl -e、標準入力はデフォルトのファイル記述子である自動入力に割り当てられるため、標準入力から読み取る(デフォルトでは改行である入力レコード区切り文字)に到達するまで同じ処理を行います。英語では、デフォルトで標準入力から1行を読み取り、変数にコンテンツを割り当てます。... | perl -ne... | perl -pe*STDIN<><STDIN>$/<>$_

  • &&and条件ですが、そこでチェーンコマンドセパレータとして使用されるため、1行後に(正常に)次のコマンドを実行して印刷します。

  • select使用しないプログラマーのトリックsleepです。このコマンドは、ファイル記述子(入力および/または出力、ファイル、ソケットおよび/またはネットソケット)のイベントをトラップするように設計されています。このコマンドを使用すると、プログラムは3種類のイベント、フィードの読み取り準備完了フィードの書き込み準備完了、およびフィード何らかのイベントが発生するのを待つことができます。4番目の引数は秒単位のタイムアウトなので、構文はです。select <feeds where wait for input>, <feeds where having to write>, <feed where something could happen>, <timeout>

より正確にするには、Time::Hiresperlモジュールを使用できます。

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

注:$.は、現在の入力行番号です。

として書かれた方が良い 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 <>

使用法:

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

最初の引数lpsはオプションの1秒あたりの行数の数値引数(デフォルト:300)

注:ファイル名が数字のみの場合、パスで指定する必要がある場合があります./3

catこのように、引数および/または標準入力として指定されたファイルを渡すことができます

したがって、次のことができます。

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

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

楽しみのために:

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

2
それはあなたがそこでやっている深刻なブードゥー教のように見えます。それはとてもクールです、私はそれを試してみました、そしてそれは動作します。私はあなたがそれをどのようにしたのか分かりません。perl selectとは一体何ですか?undef?調べることができます。すごい。
クリスストリングフェロー

2
@CrisStringfellow [OK]を、私は使用して、いくつかの説明と完全なスクリプトを追加したTime::HiRes、より精度のためのPerlモジュールを
F. HAURI

我が神よ。それは素晴らしい答えです。ありがとうございました。私はもう一度それを支持しようとしました。あなたのすばらしい説明を読んで何かを学んでいます。
クリスストリングフェロー

2
あなたも私のコメントに
賛成票を投じる

@CrisStringfellow回答編集:-pperlコマンドへの切り替えの使用により、スクリプトが軽量化されました!
F.ハウリ

11

スリープ状態でawkを使用するだけです。

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

これは私にとってはうまくいき、私の状況では、上記のスクリプトオプションではなく最良のオプションでした。この回答がなぜ投票されないのかわからない。
シチズンケプラー

2
perlソリューションとは異なり、非常に読みやすくなっています。
ガンスリンガー

1
@Gunslinger:構文system(*sleep .1")は10フォーク/秒を生成します!これは次のように書くこともできますperl -pe 'system "sleep .1"' log.txt:読みやすいが、非常に高価です(システムフレンドリーではありません!)
F.ハウリ

私もこの読みやすい答えを好みます。唯一のことは、それが出力するすべての行に対してシェルスリープコマンドを起動することです。しかし、完全に読み取り可能な1つのライナーであることは気にしません。
itsafire

0

私はパーティーに遅れていますが、これはPythonで試してみるのに役立つ学習練習になることがわかったので、私が得たものを立てます:

#!/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からの入力または引数(-i)としての入力を受け入れ、デフォルトでは1/10秒ごとに1行を書き込みますが、別の引数(-d)で変更できます。


ありがとう。このQ&Adに出くわしたとき、私はPythonでこのアイデアに似たものを開発し始めていました。Python は、F。Hauriの答えで使用されているPerlと同様の方法でselect docs.python.org/3/library/select.htmlもサポートしていることに注意してください。
ybull
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.