Файл Cat на термінал із особливою швидкістю ліній в секунду


15

Я лінивий і міг написати сценарій для цього, але я навіть лінивий, щоб думати, як це зробити.

Я часто роблю такі речі, як:

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

Іноді, дивлячись на довгий результат експерименту, мені подобається, щоб сторінка просто прокручувалась і спостерігала, як формуються та розповсюджуються послідовні шаблони. Але використання кота у файлі на 1 мільйон рядків закінчується, можливо, за 5 секунд. Це занадто швидко навіть для мене.

Чи є спосіб, щоб я уповільнив швидкість перегляду файлу, щось на зразок "утиліти прокрутки"? Я хочу швидко, але не 200k рядків в секунду (все це, імовірно, дисплей ніколи б навіть не зареєстрував).

Щось на зразок

cris$ scroll -lps=300 output.txt

І тоді, як я думаю, сидіти спиною і дивитися 300 рядків в секунду, було б ідеально.


7
Спробуйте щось на кшталт cat FILENAME | pv -l -L 900 -q. Ліміт - в байтах на секунду, а не у рядках на секунду, тому я роблю це коментарем, а не відповіддю.
Девід Шварц

Добре, що це класна утиліта, і це працює частково. Але так, це трохи похмуро, оскільки він іде після bps не lps.
Cris Stringfellow

Відповіді:


17

Короткий та читаний :

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

Я публікую ці рішення, оскільки вони невеликі та читаються, оскільки коментарі відповіді DMas сприяють такому рішенню!

Але я ненавиджу це тому, що: для цього запуску perl буде розвиватись до /bin/sleep300x / секунд!

Це великий споживач ресурсів! Також неправильно хороші рішення !!

Використання вбудованого сну в

На жаль, вбудований 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>що буде зчитувати дані зі стандартного введення до тих пір $/( вхідний роздільник записів , який за замовчуванням використовується символ нового рядка ) буде досягнута. Англійською мовою за замовчуванням <>буде прочитати один рядок зі стандартного введення та призначити вміст $_змінній.

  • &&це і стан, але використовується там в якості командного ланцюга сепаратора так після (успішно) надрукувати один рядок, роблячи таку команду.

  • selectце фокус програміста, яким не користуватисяsleep . Ця команда призначена для захоплення подій у дескрипторах файлів (входи та / або виходи, файли, сокет та / або чисті сокети). За допомогою цієї команди програма могла чекати трьох видів подій, канал готовий до читання , канал готовий до написання, а на каналі сталася якась подія . Четвертий аргумент - це тайм-аут у секундах, тому синтаксис є 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)

Примітка: якщо ім'я файлу тільки числові, ви , можливо , доведеться 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))

2
це схоже на якийсь серйозний вуду, який ти там робиш. це так круто, я спробував це, і він працює. Я поняття не маю, як ти це зробив, хоча. що, чорт забирає, перл? undef? я можу це подивитися. дивовижний.
Cris Stringfellow

2
@CrisStringfellow Добре, я додав пояснення та повний сценарій, використовуючи Time::HiResмодуль perl для більшої точності
Ф. Хаурі

Боже мій. Це приголомшлива відповідь. Дякую. Я спробував підтвердити це вдруге. Я щось вчу, читаючи ваше чудове пояснення.
Cris Stringfellow

2
Ви також можете підтримати мої коментарі ;-)
Ф. Хаурі

@CrisStringfellow Відповідь відредаговано: за допомогою -pперемикання на команду perl скрипт полегшився!
Ф. Хаурі

11

просто використовуйте awk зі сном:

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

Це працювало для мене і для моєї ситуації було найкращим варіантом, а не варіантами сценарію, наведеними вище. Не впевнені, чому ця відповідь заперечується.
Громадянин Кеплер

2
На відміну від розчину perl, він досить читабельний.
Gunslinger

1
@Gunslinger: Синтаксис system(*sleep .1")генерує 10 форк / сек! Це можна було б написати perl -pe 'system "sleep .1"' log.txt: Читаємо теж, але дуже дорого (не
підходить до

Я теж вважаю за краще цю читану відповідь. Єдине, що це буде запускати команду сну оболонки для кожного виведеного рядка. Але будучи ідеальним читаним одним лайнером, мені все одно.
itsafire

0

Я спізнююсь на вечірку, але я виявив, що це буде корисною вправою спробувати пітон, тому я поставлю те, що отримав:

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


Дякую. Я починав розробляти щось подібне до цієї ідеї в Python, коли траплявся над цим питанням та рекламою. Зауважу, що Python також підтримує функцію select docs.python.org/3/library/select.html аналогічно Perl, як використано у відповіді Ф. Хаурі.
ybull
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.