我是TCL / TK的新手。我想检查gig1端口是否是来自以下$ test变量的“trunk”或“access”。
set test {
interface gig1
switchport mode trunk
switchport trunk native vlan 1
no switchport trunk native tagged
interface gig2
switchport mode access
switchport access vlan 2
no switchport trunk native tagged
}
如何从上面的变量$ test打印,即gig1端口是trunk端口?
首先,我想过滤“gig1”以及之后出现的任何内容。
请提出您的想法?
谢谢,
库马尔
答案 0 :(得分:1)
set test {
interface gig1
switchport mode trunk
switchport trunk native vlan 1
no switchport trunk native tagged
interface gig2
switchport mode access
switchport access vlan 2
no switchport trunk native tagged
}
if {![regexp {interface gig1
switchport mode ([a-zA-Z]*)} $test line var]} {
puts "invalid parsing"
}
puts "Gig1 port is a $var port"
OUTPUT将是:
C:\Documents and Settings\Owner\Desktop>tclsh test.tcl
Gig1 port is a trunk port
C:\Documents and Settings\Owner\Desktop>
我希望它对你有用。
谢谢,
Balu P。
答案 1 :(得分:1)
foreach {a b} [set f 0 ; lmap w $test {
if {$f} {
set f 0
set w
} else {
set f [expr {$w in {interface mode}}]
continue
}
}] {
puts "Port $a is a $b port"
}
打印
Port gig1 is a trunk port
Port gig2 is a access port
这通过以下方法来执行:a)将原始列表映射到简化列表,该列表仅包含紧跟在“interface”和“mode”之后的元素,然后b)迭代该缩减列表,每个字符取两个单词时间并将它们放在输出声明中。
lmap
命令遍历列表,通常使用脚本中的当前列表项,该列表为原始列表中的每个项生成一个结果。例如,列表{a reduced list}
可以映射到包含项的字符串长度的列表:
lmap item {a reduced list} {string length $item}
# => {1 7 4}
结果列表不必包含与原始列表一样多的项目。一个可以例如生成一个列表,该列表仅包含至少包含三个字符的单词:
lmap item {to a reduced list} {
if {[string length $item] < 3} {
continue
} else {
set item
}
}
# => {reduced list}
在此上下文中,continue
命令会导致lmap
命令跳过结果列表中的一个项目。类似地,break
命令会在调用它的位置截断结果列表。
因此,如果您想要一个仅包含单词列表中所选单词的列表,则这是基本代码框架(假设原始列表位于变量test
中):
lmap w $test {
if { ‹condition› } {
set w
} else {
continue
}
}
当且仅当条件为真时,此调用将遍历原始列表并将当前单词追加到结果列表中。我们想要的条件是前面的词是“接口”和“模式”。但lmap
只能让我们一次看一个字! (其实不是真的,见下文。)
想象一下,如果前面的单词是查找单词之一,我们有一个标志变量f
,它以某种方式包含true
,否则包含false
。
lmap w $test {
if {$f} {
set w
} else {
continue
}
}
现在,我们对这个标志变量的值有什么了解?好吧,它从false
开始(在读取任何单词之前,没有前面的单词),每次我们在结果列表中添加一个单词时,它变为false
(我们添加的单词是在寻找列表中。请注意,我使用0
表示错误:它是Tcl中的合法布尔值。
set f 0
lmap w $test {
if {$f} {
set f 0
set w
} else {
continue
}
}
我们什么时候寻找“界面”和“模式”这两个词?每次标志显示false
时。当我们找到它们会发生什么?我们将标志设置为true
,这意味着下一个单词将被添加到结果列表中。
set f 0
lmap w $test {
if {$f} {
set f 0
set w
} else {
set f [expr {$w in {interface mode}}]
continue
}
}
我可以在此处使用if
命令将f
设置为1
,但将f
设置为谓词{{1}的结果会更方便}。
当我们评估上述内容时,我们会得到列表expr {$w in {interface mode}}
。我们可以通过将值插入字符串模板来使其更具可读性:
{gig1 trunk gig2 access}
为了实现这一目标,我们可以使用puts "Port $a is a $b port"
命令在每次迭代中挑选出一对单词并打印模板。
foreach
我们可以通过foreach {a b} {gig1 trunk gig2 access} {
puts "Port $a is a $b port"
}
+ foreach
脚本中的代码替换set
调用中的列表文字,将这两部分放在一起,得到简化的单词列表并打印出来。在括号内。你得到的是这个答案中的第一个代码部分。
我确实说lmap
只允许你在每次迭代中查看一个项目是不正确的。您实际上可以查看同一列表或其他列表中的多个项目,这意味着它可以工作:
lmap
但这几乎是作弊。