I'm developing a POSIX compliant script in which I want to do a dynamic replace of strings, something like:
sed "s/${pattern}/${replace}/g"
Problem: if the pattern includes the delimiting character, sed returns error, and I want to be able to use all possible characters.
Attempt (with regex): using a non printable delimiter character:
( Edited to correct syntax)
d=$(printf '\1') sed "s${d}${pattern}${d}${replace}${d}g"
Probably not portable.
Attempt (with regex): if pattern contains a certain delimiter, uses another delimiter
(edited: now in POSIX-WAY):
test "${pattern#*$delim}" != "${pattern}" && delim='@' sed "s${delim}${pattern}${delim}${replace}${delim}g"
Not bad but if the pattern contain both / more @ sed would return error.
Edited Solution (without regex): Following this, escaping chars related to regular expressions.
pattern=$(printf '%s\n' "${pattern}" | sed 's:[][\/.^$*]:\\&:g') replace=$(printf '%s\n' "${replace}" | sed 's:[\/&]:\\&:g;$!s/$/\\/')
Is there a better POSIX compliant solution with or without sed?
/
(and others?) in the pattern-to-be-matched-against (and its replacement); then that sed command is sufficient. Unless of course the pattern-to-be-matched-against contains newlines. If, on the other hand, you care only about fixed strings, Pascal strings (i.e. those with a length prefix) and some extremely simple C code can get you what you want – Fox Oct 13 '17 at 12:24case pattern in (*"$delim"*) ;; (*) delim=@; esac
. Note that "Solution 3" is POSIX. Does that not work for you? – Stéphane Chazelas Oct 13 '17 at 16:23c=$(printf '\1'); sed "s$c$pattern$c$replacement${c}g"
, but POSIX doesn't give you any guarantee that that character can be used as delimiter. It could be the newline or slash or @ or backslash character for instance. (not the case in practice though). – Stéphane Chazelas Oct 13 '17 at 16:26Stéphane and Fox: Solution 3 works and is fine for me because I need to do it in both ways with and without regex, as my question was about strings so it's okay as well. You're right about the non-printable characters, it's nothing portable, I'll look about for some way to do it.
– Emmett Brown Oct 13 '17 at 17:01