6

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?

2
  • Of possible interest: unix.stackexchange.com/q/32907/117549
    – Jeff Schaller
    Commented Oct 21, 2017 at 19:00
  • It's fine as a reference, but that's a case of replacing strings without regular expressions escaping the regex characters but I need to use regular expressions in parameters. Commented Oct 21, 2017 at 19:23

1 Answer 1

8

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.

5
  • How can I use it? your function don't print anythig Commented Oct 21, 2017 at 20:07
  • @EmmettBrown repl Foo bar < file or echo Foo | repl . '<&>' Commented Oct 21, 2017 at 20:24
  • Already, that's what I tried, but it doesn't print anything, try it yourself, maybe something is missing from that awk Commented Oct 21, 2017 at 20:46
  • @EmmettBrown oops sorry. Forgot the print Commented Oct 21, 2017 at 20:47
  • Ok, thank you for your solution, it's what I needed. Commented Oct 21, 2017 at 20:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .