Я ленивый и мог бы написать сценарий, чтобы сделать это, но мне даже лень думать, как это сделать.
Я часто делаю что-то вроде:
cris$ python runexperiment.py > output.txt
cris$ cat output.txt
Иногда, просматривая длинный вывод эксперимента, я люблю просто прокручивать страницу и смотреть, как формируются и рассеиваются последовательные шаблоны. Но использование cat на файле с 1 миллионом строк завершается примерно за 5 секунд. Это слишком быстро даже для меня.
Есть ли способ замедлить скорость просмотра файла, что-то вроде "утилиты прокрутки"? Я хочу быстро, но не 200 тыс. строк в секунду (все это дисплей, по-видимому, никогда не зарегистрирует).
Что-то вроде
cris$ scroll -lps=300 output.txt
А потом, я думаю, было бы идеально сидеть и смотреть, как проносятся 300 строк в секунду.
решение1
Короткий иудобочитаемый:
perl -pe "system 'sleep .003'" log.txt
Я публикую эти решения, потому что они небольшие и читабельные, как комментарииОтвет DMasпохоже, продвигают такое решение!
Но я ненавижу это, потому что: Для этого запуска Perl будетвилкадо /bin/sleep
300x / сек!
Это большой потребитель ресурсов! Также неправильнохорошие решения!!
С использованиемвстроенныйспать вперл
К сожалению, builtin 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 строк/сек означает 1 строку за 0,0033333333 секунды.
print
без аргумента печатает$_
что естьпространство ввода по умолчанию.называемый как
... | perl -e
,... | perl -ne
или... | perl -pe
, стандартный ввод будет автоматически назначен ,*STDIN
которомудескриптор файла по умолчанию, поэтому<>
будет делать то же самое, что и<STDIN>
which будет читать из стандартного ввода до тех пор, пока$/
(разделитель входных записейкоторый по умолчаниюновая линия) будет достигнуто. На английском языке по умолчанию<>
будет читатьсяодинстроку из стандартного ввода и присвоить содержимое$_
переменной.&&
являетсяисостояние, но используется там какразделитель цепочек командпоэтому после (успешного) вывода одной строки выполняется следующая команда.select
этотрюк программиста, который не следует использоватьsleep
. Эта команда предназначена для перехвата событий надескрипторы файлов(входы и/или выходы, файлы, сокеты и/или сетевые сокеты). С помощью этой команды программа можетждатьдля 3 видов мероприятий,лента готова к чтению,лента готова к записиипроизошло какое-то событие в ленте. Четвертый аргумент — это тайм-аут в секундах, поэтому синтаксисselect <feeds where wait for input>, <feeds where having to write>, <feed where something could happen>, <timeout>
.
Для большей точности можно использовать Time::Hires
модуль Perl:
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)Примечание: если имя файла состоит только из цифр, вам, возможно, придется указать его с помощью 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
Ради забавы:
export TIMEFORMAT='%R' ;clear ;time seq 1 $((LINES-2)) | ./catLps.pl $((LINES-2))
решение2
просто используйте awk со сном:
awk '{print $0; system("sleep .1");}' log.txt
решение3
Вместо использования интерпретатора вы можете использовать специально созданный инструмент. Он, скорее всего, установлен в вашем дистрибутиве, или вы можете установить его (apt-get install pv и т. д.)
Для отображения файла со скоростью 5 строк в секунду:
cat filename | pv --quiet --line-mode --rate-limit 5
Чтобы отобразить файл со скоростью 100 байт в секунду:
cat filename| pv --quiet --rate-limit 100
решение4
Функция Ruby sleep
поддерживает значения с плавающей точкой, поэтому вот эффективное и короткое решение, основанное на ответе @F.Hauri:
ruby -pe 'sleep 0.00333' log.txt
или
ruby -pe 'sleep (1.0/300)' log.txt