Question

match two lines with different amounts of output

  • 25 March 2024
  • 4 replies
  • 100 views

Userlevel 3
Badge

I have a problem where the two lines of this module output are not the same.  How can I put in essentially null place holders so that they resultant patterns are the "same"?

example output
Notice that module 2 does not have Fw or Sw.

Mod MAC addresses                    Hw  Fw           Sw               Status
1 a03d.6f81.0740 to a03d.6f81.074f 1.1 15.0(1r)SG12 03.07.03.E Ok
2 b0aa.777d.d010 to b0aa.777d.d017 1.0 Ok

 


I was trying to use these two patterns and tried to put in placeholds of Fw and Sw at the end of "pattern03".  But the NQE does not like this.

pattern02 =
```
Mod MAC addresses
{modNum:number} {string} to {string} {hwVer:string} {fwVer:string} {swVer:string} {modStatus:string}
```;

pattern03 =
```
Mod MAC addresses
{modNum:number} {string} to {string} {hwVer:string} {modStatus:string} {fwVer: null:string} {swVer: null:string}
```;

getMacAddrList(parsedOutput) =
foreach pattern in [pattern02, pattern03]
foreach match in blockMatches(parsedOutput, pattern)
select match;

 


4 replies

Badge

It appears that the output you are trying to parse is a fixed format.  I do realize that tabs and other non-printing characters might be lurking in the output but perhaps you can assume the row is “oneBigString” and use Sting functions to grab just certain data chunks.  Say anything from position X in the oneBigString for Y characters is a particular dataValue.

Userlevel 3
Badge

I chose to use two different user functions.  One had a pattern to match all columns.  The other to match output with two missing columns.  If there is ever a third, then I will be out of luck.

But then in the second user function.  In the Select statement.  I could add “columnX: null:String” and “columnY: null:String”.  Now all of the columns are accounted for and I can now add those two lists together.

Userlevel 3
Badge +1

If the hw and fw levels are not important. Then you could use a single pattern.

sometext = """
Mod MAC addresses Hw Fw Sw Status
1 a03d.6f81.0740 to a03d.6f81.074f 1.1 15.0(1r)SG12 03.07.03.E Ok
2 b0aa.777d.d010 to b0aa.777d.d017 1.0 Ok
""";

pattern = ```
Mod MAC addresses Hw Fw Sw Status
{n:number} {a:macAddress} to {b:macAddress}
```;

foreach x in [0]
let blocks = parseConfigBlocks(OS.UNKNOWN, sometext)
foreach match in blockMatches(blocks, pattern)
select
{
a: match.data.a,
b: match.data.b
}

The indent on the numbers may be something of interest though if we have 2 digits modules.

Userlevel 4
Badge

These can be tricky, You could leverage Approach 3 in my series on patternMatching Three techniques for pattern matching text with patternMatch, patternMatches and blockMatches

 

text = """
Mod MAC addresses Hw Fw Sw Status
1 a03d.6f81.0740 to a03d.6f81.074f 1.1 15.0(1r)SG12 03.07.03.E Ok
2 b0aa.777d.d010 to b0aa.777d.d017 1.0 Ok
""";

findTokenCount(s) = length(patternMatch(s, `{string*}`));

pattern02 =
`{modNum:number} {string} to {string} {hwVer:string} {fwVer:string} {swVer:string} {modStatus:string}`;

pattern03 =
`{modNum:number} {string} to {string} {hwVer:string} {modStatus:string}`;

normalizeBlocks(blocks) =
foreach line in blocks
foreach child in line.children
let var_count = findTokenCount(child.text)
select if var_count == 8
then patternMatch(child.text, pattern02)
else if var_count == 6
then patternMatch(child.text, pattern03)
else null : {modNum: Number, hwVer: String, modStatus: String};

foreach x in [0]
let blocks = parseConfigBlocks(OS.UNKNOWN, text)
foreach block in normalizeBlocks(blocks)
select {
block
}

 

Reply