Kir Kolyshkin (k001) wrote,
Kir Kolyshkin
k001

Category:

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: awk, fun, linux
Subscribe
Comments for this post were disabled by the author