is it possible to modify a files which are uploaded into Files in mikrotik routers via cli? I need to change some link inside it.
I can access it via
Code: Select all
file edit value-name=contents test.txt
file edit value-name=contents test.txt
is it possible to modify a files which are uploaded into Files in mikrotik routers via cli? I need to change some link inside it.
I can access edit it via
but how to change set it there through terminalCode: Select allfile edit value-name=contents test.txt
/file set test.txt contents="Did you want to write stuff at the CLI prompt?"
It's not easy, and limited. But you can :find and :pick your way through it... see viewtopic.php?t=192932#p979819yes i did, but i thought its possible to change it. So, any ideas?
/file get test.html contents
/file set test.html contents=[/file get test.html contents; :find "http://"; :pick replace with "https://"]
The reason why @normis suggested RouterOS is missing `sed` is that it's a lot of script code just to parse it. But I dug up a function that does it, at least in SOME cases. This one is borrowed from @merlinthemagic7 larger script library that I made into a simple function so it not require the rest of MTM's library. I have not test in a while, but seem to still work.i somehow stuck here
but there is no replace....of course..Code: Select all/file get test.html contents /file set test.html contents=[/file get test.html contents; :find "http://"; :pick replace with "https://"]
![]()
:put [$STR replace "http://srv1/,http://srv2" "http://" "https://"]
# https://srv1/,https://srv2
### $STR - string helpers
# from: https://raw.githubusercontent.com/merlinthemagic/MTM-RouterOS-Scripting/main/src/flash/MTM/Tools/Strings/Part1.rsc
:global STR
:set STR do={
:if ($1="trim") do={
:local param1
:if ([:typeof $2] != nil) do={
:set param1 $2;
} else={
:if ([:typeof $str] != nil) do={
:set param1 $str
}
:error "String is mandatory";
}
:set param1 [:tostr $param1]; #ROS casts lots of things as arrays. e.g. rx/tx data from interfaces
:local rLen [:len $param1];
:local rData "";
:local ch "";
:local isDone 0;
# remove leading spaces
:for x from=0 to=($rLen - 1) do={
:set ch [:pick $param1 $x];
:if ($isDone = 0 && $ch != " " && $ch != "\n" && $ch != "\r") do={
:set rData [:pick $param1 $x $rLen];
:set isDone 1;
}
}
:set rLen [:len $rData];
:local cPos $rLen;
:set isDone 0;
# remove trailing spaces
:for x from=1 to=($rLen - 1) do={
:set cPos ($rLen - $x);
:set ch [:pick $rData $cPos];
:if ($isDone = 0 && $ch != " " && $ch != "\n" && $ch != "\r") do={
:set rData [:pick $rData 0 ($cPos + 1)];
:set isDone 1;
}
}
:if ($rData = [:nothing]) do={
#always return string, the nil value is a pain
:set rData "";
}
:return $rData;
}
:if ($1="replace") do={
:local param1; #str
:local param2; ##find
:local param3; ##replace
:if ([:typeof $1] != nil) do={
:set param1 $2;
:set param2 $3;
:set param3 $4;
} else={
:if ([:typeof $str] != nil) do={
:set param1 $str;
:set param2 $find;
:set param3 $replace;
} else={
:error "String is mandatory";
}
}
:set param1 [:tostr $param1]; #ROS casts lots of things as arrays. e.g. rx/tx data from interfaces
:local rData "";
:local pos;
:local rLen [:len $param1];
:local findLen [:len $param2];
:local isDone 0;
:while ($isDone = 0) do={
:set pos [:find $param1 $param2];
:if ([:typeof $pos] = "num") do={
:set rData ($rData.[:pick $param1 0 $pos].$param3);
:set param1 [:pick $param1 ($pos + $findLen) $rLen];
:set rLen [:len $param1];
} else={
:set rData ($rData.$param1);
:set isDone 1;
}
}
:return $rData;
}
:if ($1="split") do={
:local param1; #input
:local param2; #deliminator
:if ([:typeof $2] != nil) do={
:set param1 $2;
#delemitor= case ...
:set param2 $3;
} else={
:if ([:typeof $str] != nil) do={
:set param1 $str;
:set param2 $delimitor;
} else={
:error "String is mandatory";
}
}
:local rData [:toarray ""];
:local rCount 0;
:local splitLen [:len $param2];
:if ($splitLen = 0) do={
:set ($rData->$rCount) $param1;
:return $rData;
}
:local lData "";
:local rLen [:len $param1];
:local pos;
:local isDone 0;
:while ($isDone = 0) do={
:set pos [:find $param1 $param2];
:if ([:typeof $pos] = "num") do={
:set lData [:pick $param1 0 $pos];
:set param1 [:pick $param1 ($pos + $splitLen) $rLen];
:set rLen [:len $param1];
} else={
:set lData $param1;
:set isDone 1;
}
:set ($rData->$rCount) $lData;
:set rCount ($rCount + 1);
}
:return $rData;
}
}
:global replacedContent [$STR replace [/file get FILENAME contents] "http://" "https://"]
# to see the output
:put $replacedContent
# to save output to a new file
/file add name=NEWFILENAME
/file set NEWFILENAME contents=$replacedContent
# if it wanted same file - which is bad for testing - don't need the /file add
# /file set FILENAME contents=$replacedContent