如何从变量$ test打印,即gig1端口是使用TCL regexp的trunk端口?

时间:2014-08-08 14:56:23

标签: tcl

我是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”以及之后出现的任何内容。

请提出您的想法?

谢谢,

库马尔

2 个答案:

答案 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

但这几乎是作弊。

文档:continueforeachifin operatorlmaplrangeputs,{{3 }}