:find vs. find

Does anyone know of a good tutorial (preferably a video) that explains how to use the find command?

I am particularly confused with these types of usage:

:foreach i in=[/ip addr find] do={

and

:foreach i in=[find]

and

/ip firewall address-list find list="fwaddlist"

Thank you.

The full tutorial is the manual, but the TL;DR is:

  • :find can be used to find a position of an element in an array or a position of a substring in a string:
    :local myArray {“127”;“226”;“313”} ; put [:find $myArray “226” 0] ; put ($myArray->1)
    1
    226
    :local myString “abcdef” ; :put [:find $myString “cde” 0]
    2
  • find can be used to create a list of internal IDs of configuration items of the same type that match the condition expression following the find keyword:
    /ip/address/print ; /ip/address {:put [find where interface=ether2] ; :foreach addr in=[find where interface=ether2] do={:put [get $addr network]}}
    Flags: D - DYNAMIC
    Columns: ADDRESS, NETWORK, INTERFACE

ADDRESS NETWORK INTERFACE

0 192.168.5.221/24 192.168.5.0 bridge.3
1 192.168.40.221/24 192.168.40.0 ether2
2 192.168.80.1/32 192.168.80.1 ether2
3 192.168.60.221/24 192.168.60.0 wg1
*4;*5
192.168.40.0
192.168.80.1

You wrote the same thing three times… and never :find

1 + 2 + 3 = 2 + 1 + 3 = 3 + 2 + 1 = etc. etc. etc.

:foreach i in=[/ip addr find] do={ is the same of :foreach i in=[find] if the context is already /ip address,

so temp in this case

/ip address
:local temp [find]

and on this is the same

/interface
:local temp [/ip address find]

but this is wrong, because search not on addresses

/interface
:local temp [find]

The correct form depend on context.

As noted, it’s really TWO different commands. But it generally get the right one since when you [find]… The reason is kinda dorky… the cause a new subprocess, but it take the “path” of the part of the “parent command” as the context of what’s inside. So with something like /ip/address/set [find] comment=“same-comment-on-all” - the find takes it path from the outer “/ip/address”, so the find refers to the “match attributes version” of find. So to do the “string search version”, you’d need the [:find] (or, even [/find]) form since that ONLY exists at the / “root” of the command tree. Basically there is always some cwd (current working directory) in the shell, which allow the “right” find to be used.

On the dorky side, you can see two different find’s with /console/inspect:

[admin@dude] > /console/inspect request=syntax path=find
Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM, TEXT
TYPE    SYMBOL  SYMBOL-TYPE  NESTED  NONORM  TEXT                           
syntax          collection        0  yes                                    
syntax  <in>    explanation       1  no      array or string value to search
syntax  <key>   explanation       1  no      value of key to find           
syntax  <from>  explanation       1  no      List of item numbers           
[admin@dude] > /console/inspect request=syntax path=ip,address,find
Columns: TYPE, SYMBOL, SYMBOL-TYPE, NESTED, NONORM
TYPE    SYMBOL   SYMBOL-TYPE  NESTED  NONORM
syntax           collection        0  yes   
syntax  <where>  explanation       1  no