Posted to tcl by aspect at Thu Sep 20 07:14:18 GMT 2012view raw

  1. #!/usr/bin/tclsh
  2. #
  3. # inspired by https://bitbucket.org/larsyencken/anytop/
  4. # does not include windowing function (limit to last N lines)
  5. # a bit more terminal-awareness would be nice
  6.  
  7. package require term::ansi::send
  8.  
  9. fconfigure stdin -blocking 0
  10. fileevent stdin readable consume
  11.  
  12. set ::status "Reading ..."
  13. set ::start [clock seconds]
  14. set ::lines 0
  15. set ::counts {}
  16. set ::eof 0
  17.  
  18. proc consume {} {
  19. if {[gets stdin data]<1} {
  20. if {[eof stdin]} {
  21. close stdin
  22. set ::eof 1
  23. set ::status "EOF"
  24. }
  25. } else {
  26. incr ::lines
  27. dict incr ::counts $data
  28. }
  29. }
  30.  
  31. proc topN {n counts} {
  32. lrange [lsort -integer -decreasing -stride 2 [lreverse $counts]] 0 [expr {$n*2}]
  33. }
  34.  
  35. proc elapsed {} {
  36. clock format [expr {[clock seconds]-$::start}] -format "%M:%S"
  37. }
  38.  
  39. proc refresh {} {
  40. ::term::ansi::send::clear
  41. puts "[format "%6s" [elapsed]] elapsed, $::lines lines, [dict size $::counts] distinct values"
  42. puts ""
  43. foreach {count value} [topN 20 $::counts] {
  44. puts "[format %6s $count] $value"
  45. }
  46. if {$::eof} {
  47. puts "\nReached EOF: Press ^C to exit .."
  48. } else {
  49. after 250 refresh
  50. }
  51. }
  52.  
  53. refresh
  54. vwait forever
  55.