How can I delete all files in a specific folder that matches a particular file extension (like *.rsc)? And also, how do I exclude one file (in my case the file auto-before-reset.backup under /flash)? Obviously, I’m doing something wrong as the code below won’t work:
/file remove ("/flash/".[find name=".rsc"])
I would be grateful for help and some examples how to do achieve this. Thanks!
find doesn’t quite work that way. And path’s do not start with a / …
You have to use a regular expression. The “~” use a regex to find a matching name, the \. is needed since you want a real . not the regex “.” meaning “anything” & RouterOS assumes \ is escape, so it needs to be escaped \ so the \ goes to the regex . Tricky one.
I think this is right:
/file remove [find name~"flash/.*\\.rsc\$"]
edit: See below, the $ means the file must end with .rsc - which is more correct. Although I want to same in some versions/platforms/etc paths don’t start with a /.
edit 2: But when using $, it need to be escaped since $ mean a RouterOS variable comes next, but in a regex you need the $ that @rextended shows below
FWIW, you can also use the same “find clauses” above in “/file print where” to see what matches first – remove is bad way to find out the regex are wrong. Basically it same syntax except you don’t need to wrap it in the [find name=X …] for print.
e.g. /file print where (type!=“disk”) and (name~“^flash/”) and (type=“script”) to see what might be removed/deleted, first
Is it possible to combine the statements like I’m trying to do in order to make it a oneliner like below (spoiler alert - it doesn’t work)? Also, for the auto-before-reset part, is it limited to flash/ folder only or does it apply to all folders? Can I add a statement to only delete all the files that begins with gw-01?
/file remove [find where (name~"flash/.*\\.backup\$") and !(name~"(^|/)auto-before-reset.backup\$") and (name~"flash/.*\\.rsc\$")]
Is this matching technique documented somewhere? Can regex be used?
/file remove [find where (type~"(backup|script)") and !(name~"(^|/)auto-before-reset.backup\$")]
/file remove [find where name~"(^|/)gw-01"]
Is already regex, do you not notice?
You're more likely to see how RouterOS Scripting works with my scripts, @msatter's, @Amm0's, etc. rather than in some official MikroTik document...
Anyway, it's all logical, as long as you know RegEx POSIX version without extensions.
The [find var~"regex"] syntax works the same on any command, but often you can use another combo of variable to avoid even needing a regex. As @rextended shows any of the fields can be added in the find. You'll notice the use of "type=" (which "/file/print detail" will show all the "findable" attributes, include "type"). Since matching on the type is "more exact", then say looking for file extensions strings with a regex, which may or may not use ".rsc" as extension for scripts.
And find comes up in loops, so this will print all files...
:foreach foundItem in=[/file find] do={:put "$[/file get $foundItem name]"}
The docs are vague on this whole topics – they tell you there is a find and that's it. What find always does is return a list/array of the .id= field (e.g. *1,*2,... number that's the "unique identifier" for each item in config), that match the provided attributes (or "!" not match) after the find. For example, you'll see the list of these .id= values for all you files just by doing ":put [/file find]" – since this find doesn't have any attributes that restrict the search, it means "match all" – another odd one.
As to regex, it's worth learning even if Mikrotik is forcing you. You can always try/test a regular express using https://regex101.com. Assuming you want to play with name matching, you can use the above :foreach script that will export out all the file names (without extra stuff) that you can use as the "Test Data" at regex101.com, then try the regex part from the above to see what it does.