11

Я ленивый, и я мог бы написать сценарий для этого, но я даже слишком ленив, чтобы думать о том, как это сделать.

Я часто делаю такие вещи, как:

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

Иногда, когда я смотрю на длинный результат эксперимента, мне хочется, чтобы страница просто прокручивалась и наблюдала, как формируются и рассеиваются последовательные шаблоны. Но использование cat для файла с 1 миллионом строк заканчивается за 5 секунд. Это слишком быстро даже для меня.

Есть ли способ замедлить скорость просмотра файла, что-то вроде «утилиты прокрутки»? Я хочу быстро, но не 200 тыс. Строк в секунду (все из которых, по-видимому, дисплей никогда не будет регистрироваться в любом случае).

Что-то вроде

cris$ scroll -lps=300 output.txt

И тогда я думаю, что сидеть сложа руки и смотреть, как проходит 300 строк в секунду, было бы идеально.

3 ответа3

13

Есть несколько утилит, которые позволяют вам указать скорость, например, pv , но это скорость в байтах в секунду, а не в линиях в секунду.

Но если вы действительно хотите использовать lps, вы можете сделать это:

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 строк / сек означает 1 строку на 0,0033333333 сек.

  • print без аргумента печатает $_ которое является полем ввода по умолчанию.

  • называется как ... | perl -e , ... | perl -ne или ... | perl -pe , стандартный ввод будет автоматически назначен на *STDIN который является файловым дескриптором по умолчанию , поэтому <> будет делать то же самое, что и <STDIN> который будет читать со стандартного ввода до $/ (разделитель входных записей, который по умолчанию является новой строкой) будет достигнуто. На английском языке по умолчанию <> будет читать одну строку из стандартного ввода и назначать содержимое переменной $_ .

  • && это и условие, но используются там в качестве командной цепи разделителя после (успешно) напечатать одну строку, делая следующую команду.

  • select - хитрость программиста, чтобы не использовать sleep. Эта команда предназначена для перехвата событий в файловых дескрипторах (входные и / или выходные данные, файлы, сокеты и / или сетевые сокеты). С помощью этой команды программа может ожидать 3 вида событий, канал готов к чтению , канал готов к записи, а некоторые события происходят в канале. Четвертый аргумент - это тайм-аут в секундах, поэтому синтаксис: select <feeds where wait for input>, <feeds where having to write>, <feed where something could happen>, <timeout> .

Для большей точности вы можете использовать Perl-модуль Time::Hires :

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 - необязательная строка в секунду числового аргумента (по умолчанию: 300)

Примечание: если имя файла только числовые, вы , возможно , придется specifiy их с ./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))
7

просто используйте awk со сном:

awk '{print $0; system("sleep .1");}' log.txt
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 секунды, но это можно изменить с помощью другого аргумента (-d).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .