aspect 2012-09-12: I stumbled across the Python version of this utility by accident, and immediately thought that a Tcl implementation would be much neater. It reads
stdin continuously, refreshing the display every 250ms with a summary of the most frequent ("top") lines seen on the input. Usage might be something like
tail -f /var/log/syslog | awk '{print $4" "$6}' | anytop.tcl to keep track of which hosts are generating the most log messages.
This could well be extended with ideas from
A grep-like utility or awk-like behaviour as in
owh - a fileless tclsh. It would benefit from better terminal awareness (
curses), or could trivially have a GUI attached. One interesting alteration would be a character-based histogram.
#!/usr/bin/tclsh
#
# inspired by https://bitbucket.org/larsyencken/anytop/
# does not include windowing function (limit to last N lines)
# a bit more terminal-awareness would be nice
package require term::ansi::send
fconfigure stdin -blocking 0
fileevent stdin readable consume
set ::status "Reading ..."
set ::start [clock seconds]
set ::lines 0
set ::counts {}
set ::eof 0
proc consume {} {
if {[gets stdin data]<1} {
if {[eof stdin]} {
close stdin
set ::eof 1
set ::status "EOF"
}
} else {
incr ::lines
dict incr ::counts $data
}
}
proc topN {n counts} {
lrange [lsort -integer -decreasing -stride 2 [lreverse $counts]] 0 [expr {$n*2}]
}
proc elapsed {} {
clock format [expr {[clock seconds]-$::start}] -format "%M:%S"
}
proc refresh {} {
::term::ansi::send::clear
puts "[format "%6s" [elapsed]] elapsed, $::lines lines, [dict size $::counts] distinct values"
puts ""
foreach {count value} [topN 20 $::counts] {
puts "[format %6s $count] $value"
}
if {$::eof} {
puts "\nReached EOF: Press ^C to exit .."
} else {
after 250 refresh
}
}
refresh
vwait forever