Cat 文件以每秒行的特定速度传输到终端

Cri*_*low 19 unix speed command-line cat scrolling

我很懒,我可以写一个脚本来做到这一点,但我什至懒得去想怎么做。

我经常做这样的事情:

cris$ python runexperiment.py > output.txt
cris$ cat output.txt
Run Code Online (Sandbox Code Playgroud)

有时在查看实验的长输出时,我喜欢让页面滚动并观察连续模式的形成和分散。但是在 100 万行的文件上使用 cat 可能会在 5 秒内完成。这对我来说也太快了。

有什么方法可以减慢查看文件的速度,例如“滚动实用程序”?我想要快,但不是每秒 200k 行(所有这些都可能显示无论如何都不会注册)。

就像是

cris$ scroll -lps=300 output.txt
Run Code Online (Sandbox Code Playgroud)

然后坐下来看着每秒 300 行滚动过去将是理想的,我想。

F. *_*uri 23

简短易读

perl -pe "system 'sleep .003'" log.txt
Run Code Online (Sandbox Code Playgroud)

我发布此解决方案是因为它们小且可读,因为DMas 答案的评论似乎促进了这种解决方案!

但我讨厌这一点,因为:对于这次运行,perl 会fork/bin/sleep300x/秒!

这是一个很大的资源消费者!还错了好办法!!

使用内置sleep

不幸的是,内置sleep函数仅限于整数。所以我们必须select改用:

perl -e 'print && select undef,undef,undef,.00333 while <>;'
Run Code Online (Sandbox Code Playgroud)

在perl下,print while <>可以用-p开关代替:

perl -pe 'select undef,undef,undef,.00333'
Run Code Online (Sandbox Code Playgroud)

咱们试试吧:

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
Run Code Online (Sandbox Code Playgroud)

解释:

  • 300 行/秒表示 1 行乘以 0.0033333333 秒。

  • print没有参数打印$_这是默认的输入空间

  • 被称为... | perl -e... | perl -ne或者... | perl -pe,标准输入将automaticaly分配到*STDIN这是默认的文件描述符,所以<>会做同样的<STDIN>,这将从标准输入读取,直到$/输入记录分隔符默认情况下是一个换行符)将达到。在英语中,默认情况下<>会读一个从标准输入和分配内容系$_变量。

  • &&是一个条件,但在那里用作链命令分隔符,因此在(成功)打印一行之后,执行下一个命令。

  • select程序员不使用sleep. 此命令旨在捕获文件描述符(输入和/或输出、文件、套接字和/或网络套接字)上的事件。使用这个命令,程序可以等待3 种事件,feed 准备好读取feed 准备好写入一些事件发生在 feed 上。第四个参数是以秒为单位的超时,所以语法是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)'
Run Code Online (Sandbox Code Playgroud)

注意:$.当前输入行号

最好写成 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 <>
Run Code Online (Sandbox Code Playgroud)

用法:

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

第一个参数lps是可选的每秒行数字参数(默认值:300)

注意:如果文件名只是数字,您可能必须使用 path: 指定它们./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
Run Code Online (Sandbox Code Playgroud)

为了娱乐:

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

  • 这看起来像是你在那里做的一些严肃的巫毒教。这太酷了,我试过了,它有效。我不知道你是怎么做到的。perl select 到底是什么鬼?未定义?我可以查一下。惊人的。 (2认同)
  • @CrisStringfellow 好的,为了更准确,我使用 `Time::HiRes` perl 模块添加了一些解释和完整脚本 (2认同)
  • 你也可以点赞我的评论 ;-) (2认同)

小智 11

只需将 awk 与 sleep 一起使用:

awk '{print $0; system("sleep .1");}' log.txt
Run Code Online (Sandbox Code Playgroud)

  • 与 perl 解决方案不同,它具有很强的可读性。 (2认同)

Joh*_*ohn 6

您可以使用专门制作的工具,而不是使用解释器。它可能已安装在您的发行版上,或者您可以安装它(apt-get install pv 等..)

要以每秒 5 行的速度显示文件:

cat filename | pv --quiet --line-mode --rate-limit 5
Run Code Online (Sandbox Code Playgroud)

要以每秒 100 字节的速度显示文件:

cat filename| pv --quiet  --rate-limit 100
Run Code Online (Sandbox Code Playgroud)