Search code examples
awksedrangesubstitutionbusybox

Alternative way of sed range substitution in busybox sed or awk


Given following (part of) olsrd.conf file, I want to set single settings with sed or awk (however possible) within busybox.

LoadPlugin "olsrd_httpinfo.so.0.1" {
  # defaults to 1978
  #PlParam "Port"   "8080"
  # if you dont set these, the default is to listen only on the loopback device
  #PlParam "Host"   "80.23.53.22"
  #PlParam "Net"    "10.0.0.0 255.0.0.0"
  #PlParam "Net"     "0.0.0.0 0.0.0.0"
  #PlParam "Host"   "127.0.0.1"
}

LoadPlugin "olsrd_txtinfo.so.1.1" {
  #PlParam "port"   "2006"
  #PlParam  "accept" "0.0.0.0"
}

LoadPlugin "olsrd_jsoninfo.so.1.1" {
  #PlParam "port"   "9090"
  #PlParam  "accept" "0.0.0.0"
}

Using GNU sed this works quite well in usual Linux distros with following example:

MYPORT="1234"
sed -e "/^LoadPlugin.*olsrd_txtinfo.*/ , /}/ s/.*PlParam.*port.*$/PlParam \"port\" \"$MYPORT\"/I" olsrd.conf

But in busybox (v1.33.1) this gives error: sed: unsupported command ,

As far as I understand, busybox sed does not support ranges, thus this error message.

Is there an alternative to accomplish that with busybox sed or else maybe with busybox awk?


Solution

  • Besides removing the spaces around the , operator that are the culprint here, I suggest tweaking the regex a bit more:

    • The .* at the end of the first matching line detecting pattern is redundant
    • The -e is redundant here
    • $ after the last .* in the subsitution command is redundant (.* already matches the whole line (string, in fact)
    • If you use single quotes around the sed command, you would not have to worry about how to escape double quotation marks later. Only double-quote the variable part, and keep the rest in single quotes
    • Also, if you capture the initial whitespace on the line with #PlParam (using ^\([[:space:]]*\)), you can keep the indentation (using \1 backreference in the replacement).

    So, you can use

    sed '/^LoadPlugin.*olsrd_txtinfo/,/}/ s/^\([[:space:]]*\).*PlParam.*port.*/\1PlParam "port" "'"$MYPORT"'"/I' olsrd.conf
    

    See the online demo.