Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using different delimiters in sed commands and range addresses

Tags:

sed

delimiter

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?

like image 641
DerZauberer Avatar asked May 03 '11 01:05

DerZauberer


People also ask

How do you specify a delimiter in sed?

The delimiter of choice is a forward slash (/), which is the most commonly used delimiter. However, sed can use any character as a delimiter. In fact, it will automatically use the character following the s as a delimiter. Note that the expression has to be terminated with the delimiter.

How do I run multiple sed commands in one line?

3.8 Multiple commands syntax There are several methods to specify multiple commands in a sed program. Using newlines is most natural when running a sed script from a file (using the -f option). The { , } , b , t , T , : commands can be separated with a semicolon (this is a non-portable GNU sed extension).

How do you do multiple sed replacements?

You can tell sed to carry out multiple operations by just repeating -e (or -f if your script is in a file). sed -i -e 's/a/b/g' -e 's/b/d/g' file makes both changes in the single file named file , in-place.

What does a delimiter do?

Delimiters are used in programming languages to specify code set characters or data strings, serve as data and code boundaries and facilitate the interpretation of code and the segmentation of various implemented data sets and functions.


2 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:

/regexp/
Match lines matching the regular expression regexp.

\cregexpc
Match lines matching the regular expression regexp. The c may 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.

like image 166
geekosaur Avatar answered Sep 29 '22 19:09

geekosaur


Perhaps the closest to a standard, the POSIX/IEEE Open Group Base Specification says:

[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."

like image 26
JCx Avatar answered Sep 29 '22 19:09

JCx