TCL/Expect regexp matching multiline output

expect, regex, tcl

Solution

First, an assumption: the contents of $expect_out(buffer) is a single string with embedded newlines. If it's something else, I'm wrong.

That said, you want to use the ability of regexp to pull out substrings using parentheses (). Try this:

if {[regexp {.*(prefix\-set.*end\-set).*} $expect_out(buffer) tmp matchStr]} {
    set matchStr [string map {"\n\n" "\n"} $matchStr]
}

The input has doubled newlines; the string map statement will convert them to single newlines.

Regexp will put the substring that matched the pattern in parentheses in matchStr. ($tmp holds the entire inputs string, since regexp succeeded.) You can have multiple sets of parentheses if you want, matching multiple symbols in the input. For more information, check out http://www.tcl.tk/man/tcl8.5/TclCmd/re_syntax.htm and http://wiki.tcl.tk/989.

Problem

I am having difficulty matching a pattern being returned from a cisco router. Here is the $expect_out(buffer) output of the sh run prefix-set xxx command: ``` 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 ! ``` Using regexp, I would like to match "prefix-set" through "end-set", eliminating everything before and after. I am looking for the data to ultimately look like this: ``` 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 ``` The "abc_123-99999-in" and the returned prefixes will always be different. The code I am currently using: ``` 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'" } ``` Any ideas on how I can clean up the returned data? Thanks!!

Original source