Community discussions

MikroTik App
 
mike548141
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 51
Joined: Sun Aug 16, 2020 5:14 am

Using where to see if value is in an array

Fri Nov 12, 2021 3:38 am

How are people scripting the use of the where statement to find a value in an array? (see example below)

In this example I am trying to see if a bridge VLAN contains an interface name in its array of untagged interfaces. The issue I have is terminating the value in the example below i.e.
untagged~($ifname . ";")
* If I do append the semi-colon then it works perfectly unless the value I'm looking for is the last one in the array, at which point it does not find it as the array does not end with a ;
* If I don't append the semi-colon to $ifname the match works like a starts with/partial match rather than matching the whole value in the array. For example if ifname=ether2 and untagged=ether1;ether20;bond1 the where statement below will match ether20 and output a 1 but it should be 0.
:if ([ /interface bridge vlan print count-only where bridge=$lifbridge vlan-ids=$nativevlan untagged~($ifname . ";"); ] > 0) do={ ... };
I'm getting around this currently by looping through each VLAN on the bridge that the interface is assigned to, and then looping through each interface in tagged/untagged.

P.S> Unrelated but fingers crossed that Mikrotik add an "else if " command to RouterOS
Last edited by mike548141 on Sun Nov 14, 2021 10:22 am, edited 1 time in total.
 
sin3vil
newbie
Posts: 34
Joined: Sat May 26, 2018 10:05 pm

Re: Using where to see if value is in an array  [SOLVED]

Fri Nov 12, 2021 12:03 pm

Hi,

~ tries to do a regex match on the value as a string.
You can build your regex to ensure it only matches required result : "whatever(;|$)"

i.e.
global matcher do={
local string "ether11;ether2;ether21;ether22"
if ($string~($1."(;|\$)")) do={
put ("$1 is in string")
} else {
put ("no match")
}
}
results :
[sini@sini2] > $matcher ether2
ether2 is in string
[sini@sini2] > $matcher ether1
no match
[sini@sini2] > $matcher ether22
ether22 is in string
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Using where to see if value is in an array

Fri Nov 12, 2021 8:21 pm

fixed some errors on example...
:global matcher do={
    :local string "ether11;ether2;ether21;ether22"
    :if ( $string~"$1(;|\$)" ) do={
        :put "$1 is in string"
    } else={
        :put "no match"
    }
}

untagged~("test;") match anything that contain "test;"
untagged~("test") match anything that contain "test"
"test(;|$)" match anything that contain "test;" or end by "test"

"(^|;)test(;|$)" match exactly what: ( (start with test or the record start with test) and (the record end with test or end with test) )

so:
untagged~"(^|;)$ifname(;|\$)"


/interface bridge vlan
:if ([:len [find where bridge=$lifbridge and vlan-ids=$nativevlan and untagged~"(^|;)$ifname(;|\$)"]] > 0) do={
    :put "some VLANs found"
}
 
mike548141
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 51
Joined: Sun Aug 16, 2020 5:14 am

Re: Using where to see if value is in an array

Sun Nov 14, 2021 10:26 am

~ tries to do a regex match on the value as a string.
Thanks for replying @sin3vil and @rextended. For some reason I had it in my head that ~ was a partial match (aka contains vs = or !=) but I went back to the docs after posting my question here and saw it was actually regex as you say. But ran out of energy before testing it out.

Thanks for the example code! I will tweak the script now.

Cheers,

MC

Who is online

Users browsing this forum: m4rk3J and 20 guests