我无法匹配从cisco路由器返回的模式。这是sh run prefix-set xxx命令的$ expect_out(缓冲区)输出:
sh run prefix-set abc_123
RP/0/RSP0/CPU0:a1.rtr2#sh run prefix-set abc_123
RP/0/RSP0/CPU0:a1.rtr2#sh run prefix-set abc_123-99999-in
Fri Dec 6 21:12:16.863 GMT
prefix-set abc_123-99999-in
2.245.109.0/24 le 32,
2.245.196.0/22 le 32,
2.245.246.0/23 le 32,
2.245.248.0/23 le 32
end-set
!
使用regexp,我想通过“end-set”匹配“prefix-set”,消除之前和之后的所有内容。
我正在寻找最终看起来像这样的数据:
prefix-set abc_123-99999-in
2.245.109.0/24 le 32,
2.245.196.0/22 le 32,
2.245.246.0/23 le 32,
2.245.248.0/23 le 32
end-set
“abc_123-99999-in”和返回的前缀将始终不同。
我目前使用的代码:
expect "\r"
send_user ">>>>> Executing: sh run prefix-set $ccname <<<<\n"
#show prefix-set. \t tabs out the name for completion
send "sh run prefix-set $ccname\t\r"
expect "!\r"
if {[regexp {^.*Kprefix\-set.*$} $expect_out(buffer) pfx]} {
set pfx [string trimright $pfx]
puts $output "URL is: '$pfx'"
}
有关如何清理返回数据的任何想法?
谢谢!
答案 0 :(得分:4)
首先,假设:$ expect_out(缓冲区)的内容是带有嵌入换行符的单个字符串。如果是别的话,我错了。
那就是说,你想使用regexp的能力来使用括号()来拉出子串。试试这个:
if {[regexp {.*(prefix\-set.*end\-set).*} $expect_out(buffer) tmp matchStr]} {
set matchStr [string map {"\n\n" "\n"} $matchStr]
}
输入新线增加了一倍;字符串map语句将它们转换为单个换行符。
Regexp会将匹配模式的子字符串放在matchStr的括号中。 ($ tmp保存整个输入字符串,因为regexp成功。)如果需要,可以有多组括号,匹配输入中的多个符号。有关详情,请查看http://www.tcl.tk/man/tcl8.5/TclCmd/re_syntax.htm和http://wiki.tcl.tk/989。
答案 1 :(得分:0)
string map {\n\n \n} ...
操作的缺点是它只减少了多行空行。对于任意数量的空行,lmap
或regsub
操作更好。对于有问题的字符串,人们还可以利用相关的“前缀设置”字符串从一行的开头开始的事实:
set noblanks [regsub -all {\n+} $expect_out(buffer) \n]
regexp -lineanchor ^prefix-set.*end-set $noblanks result
或者,更紧凑:
regexp -lineanchor ^prefix-set.*end-set [regsub -all {\n+} $expect_out(buffer) \n] result
如果匹配则设置result
变量,否则设置不设置(除非已设置)。查看regexp
调用的结果,或者测试info exists result
。
% set result
prefix-set abc_123-99999-in
2.245.109.0/24 le 32,
2.245.196.0/22 le 32,
2.245.246.0/23 le 32,
2.245.248.0/23 le 32
end-set
文档: info, regexp, regsub, set, Syntax of Tcl regular expressions