I am using sed in a shell script to edit filesystem path names. Suppose I want to replace
/foo/bar with
/baz/qux However, sed's s/// command uses the forward slash / as the delimiter. If I do that, I see an error message emitted, like:
▶ sed 's//foo/bar//baz/qux//' FILE sed: 1: "s//foo/bar//baz/qux//": bad flag in substitute command: 'b' Similarly, sometimes I want to select line ranges, such as the lines between a pattern foo/bar and baz/qux. Again, I can't do this:
▶ sed '/foo/bar/,/baz/qux/d' FILE sed: 1: "/foo/bar/,/baz/qux/d": undefined label 'ar/,/baz/qux/d' What can I do?
63 Answers
You can use an alternative regex delimiter as a search pattern by backslashing it:
sed '\,some/path,d' And just use it as is for the s command:
sed 's,some/path,other/path,' You probably want to protect other metacharacters, though; this is a good place to use Perl and quotemeta, or equivalents in other scripting languages.
From man sed:
1
/regexp/
Match lines matching the regular expressionregexp.
\cregexpc
Match lines matching the regular expressionregexp. Thecmay be any character other than backslash or newline.
s/regular expression/replacement/flags
Substitute the replacement string for the first instance of the regular expression in the pattern space. Any character other than backslash or newline can be used instead of a slash to delimit the RE and the replacement. Within the RE and the replacement, the RE delimiter itself can be used as a literal character if it is preceded by a backslash.
Perhaps the closest to a standard, the POSIX/IEEE Open Group Base Specification says:
0[2addr] s/BRE/replacement/flags
Substitute the replacement string for instances of the BRE in the pattern space. Any character other than backslash or newline can be used instead of a slash to delimit the BRE and the replacement. Within the BRE and the replacement, the BRE delimiter itself can be used as a literal character if it is preceded by a backslash."
When there is a slash / in theoriginal-string or the replacement-string, we need to escape it using \. The following command is work in ubuntu 16.04(sed 4.2.2).
sed 's/\/foo\/bar/\/baz\/qux/' file