k001
k001
:...

April 2032
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

k001 [userpic]
output rate limiter in awk

В процессе обдумывания OpenVZ bug #1066 написал несколько интересных штук на awk.

Положим, у нас есть программа, которая много-много печатает (например, tar -vx при распаковке большого количества маленьких файлов). А нам много-много не надо, нам надо просто видеть, что что-то происходит.

Вот самый простой вариант -- каждую 1000 входных строк печатать число, количеству "проглоченных" строк соответствующее:

awk '(NR % 1000 == 0) {printf NR "\r"}'

Возможно, что более информативно будет печатать не количество строчек, а сами эти строчки (не все, конечно, а некоторое). Вот этот код печатает каждую тысячную строчку из stdin:

awk '(NR % 1000 == 0) {printf "\033[2K%s\r", $0}'

В общем случае этот параметр 1000 надо подбирать -- мы же априори не знаем, как быстро нам подают строчки на вход. Возможный выход из ситуации -- печатать каждую тысячную строчку, но не чаще раза в секунду, вот:

awk '(NR % 1000 == 0) {t=systime(); if (t!=t1) {printf "\033[2K%s\r", $0; t1=t}}'

Можно, впрочем, печатать и номер строки, и саму строку:

awk '(NR % 1000 == 0) {t=systime(); if (t!=t1) {printf "\033[2K[%d] %s\r", NR, $0; t1=t}}'

Дальнейшее усовершенствование -- обрезать строки, которые шире ширины терминала -- оставляю читателям в качестве домашнего упражнения.

Кстати, забавно, что получилась такая своеобразная русская рулетка, например, вот некоторые файлы на вашем диске:

ls -lR / 2>/dev/null | awk '(NR % 1000 == 0) {t=systime(); if (t!=t1) {printf "\033[2K%s\r", $0; t1=t}}'

PS по коду всё должно быть понятно, за исключением, может быть, \033[2K -- это очистка текущей строки. Нужна в том случае, если следующая строчка короче предыдущей, чтобы мусора на экране не оставалось.

Tags: , ,
Comments

>Дальнейшее усовершенствование -- обрезать строки, которые шире ширины терминала -- оставляю читателям в качестве домашнего упражнения.

substr() ? Вот только сходу (без гугла) не скажу, как определить ширину терминала.

я знаю два способа

echo $COLUMNS
stty size