You can associate multiple sed expressions with a character ; . Look at each separately here.
The first expression /^void.*{$/!b has a delimiter expression between delimiters / 's. It corresponds to:
^ - start of line
void - followed by the characters "void"
.* - followed by something
{ - followed by the left curly figure
$ - followed by the end of the line
The modifier in this first expression !b means that if the match does not match, abort the sed evaluation.
Expression :a is a label. It was used with the goto-like sed function called branching. We will see how labels are used in the following expression.
The expression /\n}$/bb matches:
\n - new line
} - followed by right curly
$ - followed by the end of the line
The bb modifier means that if you find a match, โbranchโ to label b. Label b is defined in a later expression as :b .
The expression $!{N;ba} should be read as a unit, although it does ; In the middle. The columns in this case are a sequence of instructions that must be executed together.
$! - if this is not the end of the input
{ - run a group of commands (in this case there are two)
N - read another line, silently
ba - branch for marking
} - final group of commands
Next is the label :b , which we will hit when we match one } on the line, through the expression /\n}$/bb .
Finally, there are two replacement patterns that are pretty standard regex. s before the expression essentially means s/find_this/replace_it_with_this/ . In the case s/\n/&test1&/ we have:
\n - find a new line
/ - and replace it with
& - the thing that was matched in the first expression (in this case, in a new line)
test1 - word test1
& - and again the thing that was matched
So basically s/\n/&test1&/ means replacing the next \n with \ntest1\n .
The last expression is similar, but introduces something called captures. Captures let you still match everything, but keep everything between \( and \) for use in the replacement part of an expression. For example, s/a\(b\)c\(d\)e/\1 \2/ displays bd if the input string abcde . In this example, \1 and \2 are replaced by things that are captured in shielded pairs, b and d , respectively.
s is a lookup pattern:
/ - find
\( - and enter into the replacement variable \1
. - nothing
* - and any quantity
\n - including the first new line that you encounter
\) - (end of capture for \1 )
\( - and enter into the replacement variable \2
. - nothing
* - and any quantity
\n - including the first new line that you encounter
\) - (end of capture for \2 )
/ - and replace it with
\1 - the first thing that was captured,
test2\n - test2 \ n,
\2 - and the second thing is captured.