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.