Downey_HUff
Downey_HUff

Reputation: 191

extracting particular values from output

i have a pagent router output as

set pagent_ouput "Interface:    Ethernet2/3

packetfilter:   2500 123bps 456.123pps
packetfilter:   2300 345bps 345.548pps

Interface:    Ethernet3/4

packetfilter:   2500 123bps 896.163pps
packetfilter:   2300 345bps 675.748pps"

ethernet interfaces varies....i want to extract pps value for each ethernet interface i want something like { {456.123 345.548} {896.163 675.748}}

if pagent_output varies as

set pagent_output "Interface:    Ethernet2/3

packetfilter:   2500 123bps 456.123pps
packetfilter:   2300 345bps 345.548pps
packetfilter:   2300 645bps 445.548pps
packetfilter:   2300 745bps 545.548pps

Interface:    Ethernet3/4

packetfilter:   2500 123bps 656.123pps
packetfilter:   2300 345bps 745.548pps
packetfilter:   2300 345bps 845.548pps
packetfilter:   2300 345bps 945.548pps

Interface:    Ethernet3/5

packetfilter:   2500 123bps 156.123pps
packetfilter:   2300 345bps 255.548pps
packetfilter:   2300 345bps 375.548pps
packetfilter:   2300 345bps 395.548pps"

the list will be { {456.123 345.548 445.548 545.548} {656.123 745.548 845.548 945.548} 
{156.123 255.548 375.548 395.548}}

Upvotes: 1

Views: 256

Answers (2)

Donal Fellows
Donal Fellows

Reputation: 137587

First, you will want to split the text up into pieces on the Interface lines, and then you want to extract the data from those pieces. (It's easier to split the problem up that way, even though there are other ways to do it, because it is easier to think about larger problems in terms of connected smaller problems rather than one big problem.) We're going to use regular expressions to do the extraction; to follow along with Tcl's exact dialect of REs, be sure to check the relevant manual page.

To split the data into sections for each interface, I recommend using the textutil::split::splitx command from Tcllib.

package require textutil::split

set interface_data [textutil::split::splitx $pagent_output {(?n)^Interface:.*$}]

Then, we want to get the pps values out of the data for each interface; regexp with the -all -inline options is the best tool for this:

set result {}
foreach item [lrange $interface_data 1 end] {
    lappend result [regexp -all -inline {\m[0-9.]+(?=pps)} $item]
}

Now, the result variable holds what you are after.


If you've upgraded to Tcl 8.6, you can do this all a bit shorter through the use of lmap:

package require textutil::split

set result [lmap item [lrange [textutil::split::splitx $pagent_output {(?n)^Interface:.*$}] 1 end] {
    regexp -all -inline {\m[0-9.]+(?=pps)} $item
}]

It's still the same basic idea though; textutil::split::splitx to divide things up (because doing that by hand is a bit of a drag) and regexp -all -inline in a loop to extract the info.

Upvotes: 1

reversebind
reversebind

Reputation: 1316

I have done a little extracting output from a cisco router for interface output. Not sure is this is of anything help.

tcl regexp command is your best bet I think. I am not an expert in tcl but with regexp you can match anything you want that is in parenthesis.

set output "
packetfilter:   2500 123bps 456.123pps
packetfilter:   2300 345bps 345.548pps
packetfilter:   2300 645bps 445.548pps
packetfilter:   2300 745bps 545.548pps"

foreach line [split $output "\n"] {
set findpps [regexp {bps\s([0-9]+)\.([0-9]+)pps} $line fullmatch sub1 sub2]
if {$findpps == 1} {
puts "Int Eth2/3 PPS output is $sub1.$sub2"
}
}

split the output into lines if the regular expression is found it will = 1. sub1 is the first number after "123bps" and sub2 is the second number

In cisco land if you wanted the values of all interfaces you can write a script that gets all the interface output via the "exec command" and parse through all the data that way.

Upvotes: 0

Related Questions