Skip to main content

Some output from commands has a comma immediately after the output number:

 

nat-limit statistics:

 max entry: max allowed 0, used 0, missed 0

 

I can parse the result as a string, but want to grab the data as a number so I can do other operations (math/comparison/etc).

 

I can remove the comma with a replacement function (thanks ​@GaryB )

cleanComma(s) = replaceMatches(s, ",", "");

 

however the output, even while being a number (0) is still considered a string.

 

Looking at toNumber, the documentation gives the warning it is for IPv4 addresses only.

 

Is there a way to convert a string into a number variable type?

Hi ​@CarlB ,

One way to do it is to use pattern match like this (assuming your string is in a variable s):

patternMatch(s, `{number}`)

This call will return a number or null (which can be checked with isPresent()).


@Andreas  - I was trying inside a blockpattern

NatStatisticsPattern =

 ```

Total active translations: {TotActXlate: float} {XlateStatic: string} static, {XlateDynamic: float} dynamic; {XlateExtended: float} {string}

Hits: {XlateHits: float}  Misses: {XlateMisses: float}

Expired translations: {XlateExpired: float}

Dynamic {string}

nat-limit statistics:

 max entry: max allowed {MaxConfiguredXlate: string} used {string}

In-to-out drops: {string}

```;

which gives an error if I change ‘MaxConfiguredXlate’ to a type number.

The actual command output is this:

Command: show ip nat statistics
Total active translations: 0 (0 static, 0 dynamic; 0 extended)
Outside interfaces:
Tunnel1500
Inside interfaces:
GigabitEthernet0/0/0
Hits: 3420 Misses: 13
Expired translations: 13
Dynamic mappings:
-- Inside Source
uId: 1] route-map RM_EC_NAT interface Loopback1500 refcount 0
nat-limit statistics:
max entry: max allowed 0, used 0, missed 0
In-to-out drops: 0 Out-to-in drops: 0
Pool stats drop: 0 Mapping stats drop: 0
Port block alloc fail: 0
IP alias add fail: 0
Limit entry add fail: 0

 

 

I cleared out the commas with the cleancommas and changed my pattern to remove the ‘,’ on the first line and still get an error if I try to call it as a number.

 

Or are you saying I have to do an additional step of 

 

patternMatch(MaxConfiguredXlate, '{number}')

?


Yes, I was saying that you can use the extra patternMatch(s, `{number}`) call after you get the data out of the first pattern match.

I think using regular expressions might actually be more convenient for parsing this output, because it provides a bit more flexibility in parsing numbers and addresses. 


@Andreas - can you give an example given the code? I’m getting parsing errors so guessing I am using it wrong.


NatStatisticsPatternNoCommas =
```
Total active translations: {TotActXlate: float} {XlateStatic: string} static {XlateDynamic: float} dynamic; {XlateExtended: float} {string}
Hits: {XlateHits: float} Misses: {XlateMisses: float}
Expired translations: {XlateExpired: float}
Dynamic {string}
nat-limit statistics:
max entry: max allowed {MaxConfiguredXlate: string} used {string}
In-to-out drops: {string}
```;

cleanComma(s) = replaceMatches(s, ",", "");

foreach device in network.devices
foreach command in device.outputs.commands
where command.commandText == "show ip nat statistics"

foreach x in x1]
let ParsedResponse = parseConfigBlocks(OS.UNKNOWN, cleanComma(command.response))
foreach r in blockMatches(ParsedResponse, NatStatisticsPatternNoCommas)


select {
Device: device.name,
Model: device.platform.model,
MaxNATs: r.data.MaxConfiguredXlate,
NatHits: r.data.XlateHits,
NatMisses: r.data.XlateMisses,

}

 


This is late, but I’ll still pile on here. There is an example of this in the Forward Library. 

Cisco WS-C3850 Overutilized TCAM Check
FQ_916976063d3cd8adde94d4afc178724fcc2ee088

 

Directly or indirectly connected routes            16384/7168       5051/6484

It probably would have worked fine to replaceMatches the “/” at the beginning.  But I did the replacement later.  Which means first I had to pull this data out as a “string”.

Later I pass the value 16384/7168 up into a user function where I separate the two numbers and then patternMatch them into the data type of Number.

// The TCAM values are slash separated, for example 16384/7168.
getTcamValues(text) =
patternMatch(replace(text, "/", " "), `{left:number} {right:number}`);

Which means there are multiple ways to “skin this cat”.  You can covert the data type later in your query by using the “patternMatch” to define your variable as a different data type.

Depends on which one makes more sense to you or is more readable to you.


Reply