Shell – A posix-compliant function for replace text with parameters and regex

posixregular expressionreplaceshell-script

I'm making a function with a replacement of strings using regular expressions in a secure way, without possibility to inject characters, and without renouncing the use of regular expressions:

#! /bin/sh

stringer()
{
    pattern="${1}"
    replace="${2}"

    printf '%s\n' "examp/e w\\th sed: " | sed "s/${pattern}/${replace}/g"
}

stringer "\\/" "l"

So far so good, but if I use:

stringer "/" "l"

it would result in a sed error, about this I know that the input parameters can be escaped, but then it wouldn't can be used with regular expressions, and I want to be able to use it with regex, any suggestions with or without sed but without extensions for posix-compliant way?

Best Answer

Escaping the / only is very difficult to do with sed because for instance it would have to be escaped in:

Foo/bar
Foo[XY]/
Foo\[/x\]
Foo\\/bar

But not in

Foo [/x]bar
Foo [^]/x]bar
Foo [x[:blank:]/y]
Foo\/bar

It may be easier to use awk instead

repl() {
  PATTERN=$1 REPL=$2 awk '
    {gsub(ENVIRON["PATTERN"], ENVIRON["REPL"]); print}'
}

However note that awk's regexps are extended regular expressions (as opposed to the basic ones in sed), and while it understand & in the replacement part to mean the matched portion, it does not support sed's \1. Except with busybox awk, it doesn't support back references in the pattern either.

Here you could stick with your approach but document the fact that / needs to be escaped. You'll need to document which are the regexp operators anyway (as the user may need to escape them), that newline can't be matched, and that newline must be escaped in the replacement and the special behaviour of & and backslash there.

Related Question