Tcl parsing for a command output exits without giving any output -
i trying write script parse following output -
dev1# show stats 20:01:02-180 (stats) id=1a2b3c work stats -- -- -------- overall -------- t1 t2 total t5 t6 total container 3 3 0 3 3 3 operatioms 3 3 0 3 3 3 docker 3 3 0 3 3 3 tcl 3 3 0 3 3 3 app 3 3 0 3 3 3 external 1 4 0 intra 2 6 0 incoming locks 8 6 0 outgoing locks 4 3 0 race-condition times 10 20 23 threads/usage 45 56 70 power 2.3 10 consumption 20.3% 29% ----------------------------------------------------------------------- separate command ----------------------------------------------------------------------- dev1# show usage 20:01:08-100 os: 48270 % core: 4524 % user: 90 %
unfortunately device output not formatted well.
while browsing through tcl blogs, found 1 blog had following code -
set input [dev1 run "show stats"] array unset output array set output {} foreach line [split $input "\n"] { if {[regexp {^([^:]+?)\s*:\s*(\s+)\s*(\s+)?$} $line ]} { set key [string tolower $key 0 0] set output($key) $value if {[string length $units]} { set output(${key}unit) $units } } } foreach {key value} [array output] { puts [list $key $value] }
i unable work. although, blog steps followed. can point out few hints solve issue. new forum , learn more.
expected output
stats { {time 20:01:02-180} {id 1a2b3c} {cmd stats} {now {t1 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} {extrenal 3} {intra 2} {incoming_locks 8} {outgoing_locks 4} {race-condition_times 10} {threads/usage 45}} {t2 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} {extrenal 4} {intra 6} {incoming_locks 6} {outgoing_locks 3} {race-condition_times 20} {threads/usage 56}} {total {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} {extrenal 4} {intra 6} {incoming_locks 0} {outgoing_locks 0} {race-condition_times 23} {threads/usage 70}} } {overall {t5 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} } {t6 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} } {total {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} } } {power {current 2.3} {total 10}} {consumptiomn {current 20.3%} {total 29%}} } ----------------------------------------------------------------------- ----------------------------------------------------------------------- usage { {time 20:01:08-100} {os 48270%} {core 4524%} {user 90%} }
thanks
now freaky output format.
it's not hard parse text format, producing output format takes doing.
here 2 commands parse output stats
/ usage
commands , harvest data dict structures:
proc parsestats txt { set data {} set keys1 {{now t1} {now t2} {now total} {overall t5} {overall t6} {overall total}} set keys2 {{now t1} {now t2} {now total}} foreach line [split [string trim $txt] \n] { switch -regexp -matchvar m $line { {^\s*(container)\m\s+(.*)} - {^\s*(operations)\m\s+(.*)} - {^\s*(docker)\m\s+(.*)} - {^\s*(tcl)\m\s+(.*)} - {^\s*(app)\m\s+(.*)} { lassign $m -> keystring values foreach key $keys1 val $values { dict set data stats {*}$key $keystring $val } } {^\s*(external)\m\s+(.*)} - {^\s*(intra)\m\s+(.*)} - {^\s*(incoming locks)\m\s+(.*)} - {^\s*(outgoing locks)\m\s+(.*)} - {^\s*(race-condition times)\m\s+(.*)} - {^\s*(threads/usage)\m\s+(.*)} { lassign $m -> keystring values set keystring [string map {{ } _} $keystring] foreach key $keys2 val $values { dict set data stats {*}$key $keystring $val } } {^\s*(power)\m\s+(.*)} - {^\s*(consumption)\m\s+(.*)} { lassign $m -> keystring values foreach lbl {current total} val $values { dict set data stats $keystring $lbl $val } } ^\\d { dict set data stats time [lindex $line 0] dict set data stats cmd [string trim [lindex $line 1] ()] dict set data stats id [lindex [split [lindex $line 2] =] 1] } } } return $data } proc parseusage txt { set data {} foreach line [split [string trim $txt] \n] { switch -regexp -matchvar m $line { {^\s*(os)\m:\s+(.*)} - {^\s*(core)\m:\s+(.*)} - {^\s*(user)\m:\s+(.*)} { lassign $m -> keystring values dict set data usage $keystring [join $values {}] } ^\\d { dict set data usage time $line } } } return $data }
assuming output stats
command in statstext
variable, , output usage
command in usagetext
variable, can construct these dictionary structures (note actual output white-space-packed: have added newlines , indents readability).
% set stats [parsestats $statstext] % set stats stats { time 20:01:02-180 cmd stats id 1a2b3c { t1 {container 3 docker 3 tcl 3 app 3 external 1 intra 2 incoming_locks 8 outgoing_locks 4 race-condition_times 10 threads/usage 45} t2 {container 3 docker 3 tcl 3 app 3 external 4 intra 6 incoming_locks 6 outgoing_locks 3 race-condition_times 20 threads/usage 56} total {container 0 docker 0 tcl 0 app 0 external 0 intra 0 incoming_locks 0 outgoing_locks 0 race-condition_times 23 threads/usage 70} } overall { t5 {container 3 docker 3 tcl 3 app 3} t6 {container 3 docker 3 tcl 3 app 3} total {container 3 docker 3 tcl 3 app 3} } power {current 2.3 total 10} consumption {current 20.3% total 29%} } % set usage [parseusage $usagetext] % set usage usage { time 20:01:08-100 os 48270% core 4524% user 90% }
if can, urge use dictionaries these instead of output format in question. easier process dictionaries.
if must keep output format shown, following command converts dict
structure string functionally equivalent, if not white-space equivalent:
proc prettyprintdict dict { dict {k v} $dict { if {[llength $v] == 1} { append res "{$k $v}\n" } else { append r [prettyprintdict $v] append res "$k {\n$r}\n" set r {} } } return $res } % puts [prettyprintdict [parsestats $statstext]] % puts [prettyprintdict [parseusage $usagetext]]
note relies on values being words without whitespace.
documentation: append, dict, foreach, if, lassign, proc, puts, return, set, split, string, switch
Comments
Post a Comment