命令输出的 Tcl 解析退出而不给出任何输出
Tcl parsing for a command output exits without giving any output
我正在尝试编写一个可以解析以下输出的脚本 -
dev1# show stats all
20:01:02-180 (stats) ID=1a2b3c
Work Stats -- Now -- -------- 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 %
很遗憾,设备输出格式不正确。
在浏览 tcl 博客时,我发现了一个包含以下代码的博客 -
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 get output] {
puts [list $key $value]
}
我无法让它工作。虽然,按照博客的步骤。有人可以指出一些提示来解决这个问题。我是论坛的新手,想了解更多。
预期输出
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%}
}
谢谢
这是一种奇怪的输出格式。
解析文本格式并不难,但生成输出格式需要一些工作。
这里有两个命令解析 stats
/ usage
命令的输出并将数据收集到字典结构中:
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
}
假设stats
命令的输出在statsText
变量中,usage
命令的输出在usageText
变量中,可以构造这些字典结构(请注意,实际输出是白色的-space-packed:我添加了换行符和缩进以提高可读性)。
% set stats [parseStats $statsText]
% set stats
stats {
time 20:01:02-180
cmd stats
id 1a2b3c
Now {
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%
}
如果可以的话,我强烈建议您使用这些字典来代替问题中的输出格式。处理字典会容易很多。
如果必须保持所示的输出格式,则以下命令将 dict
结构转换为功能等效的字符串,如果不是 white-space 等效的:
proc prettyPrintDict dict {
dict for {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]]
请注意,它依赖于所有值都是没有白色的单词space。
文档:append, dict, foreach, if, lassign, proc, puts, return, set, split, string, switch
我正在尝试编写一个可以解析以下输出的脚本 -
dev1# show stats all
20:01:02-180 (stats) ID=1a2b3c
Work Stats -- Now -- -------- 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 %
很遗憾,设备输出格式不正确。
在浏览 tcl 博客时,我发现了一个包含以下代码的博客 -
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 get output] {
puts [list $key $value]
}
我无法让它工作。虽然,按照博客的步骤。有人可以指出一些提示来解决这个问题。我是论坛的新手,想了解更多。
预期输出
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%}
}
谢谢
这是一种奇怪的输出格式。
解析文本格式并不难,但生成输出格式需要一些工作。
这里有两个命令解析 stats
/ usage
命令的输出并将数据收集到字典结构中:
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
}
假设stats
命令的输出在statsText
变量中,usage
命令的输出在usageText
变量中,可以构造这些字典结构(请注意,实际输出是白色的-space-packed:我添加了换行符和缩进以提高可读性)。
% set stats [parseStats $statsText]
% set stats
stats {
time 20:01:02-180
cmd stats
id 1a2b3c
Now {
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%
}
如果可以的话,我强烈建议您使用这些字典来代替问题中的输出格式。处理字典会容易很多。
如果必须保持所示的输出格式,则以下命令将 dict
结构转换为功能等效的字符串,如果不是 white-space 等效的:
proc prettyPrintDict dict {
dict for {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]]
请注意,它依赖于所有值都是没有白色的单词space。
文档:append, dict, foreach, if, lassign, proc, puts, return, set, split, string, switch