So here is my very specific task. I have patterns of type
.*[class|namespace|struct].*
(this is one part of the pattern, to be precise),
then an arbitrary amount of newlines \n
or spaces intermixed (may be 0 newlines, but at least 1 space), and right after that I have a very specific pattern – I basically know that this line always comes in the way of
{specific_text;^
This was the second part of the pattern. That is it.
Notes: if there is part one of the pattern, then there definitely exists part 2.
The task
I need to replace each line with custom text that comes right before the corresponding part one pattern, into single curly brace and a newline symbol, like this – ''{\n''.
How do I do it with a bash shell, awk and sed?
Note. So you can see that basically I want to change the first line that matches my very specific pattern, AND which is the first among its kind after the class|namespace|struct keyword.
Example.
class A { specific_text;
is transformed into
class A {
And this
class A
{ specific_text;
becomes
class A
{
Please note in the last example we preserved the newlines.
Best Answer
It works like this:
class
ornamespace
orstruct
is found,sed
does nothing more than its default action: it prints incoming lines as they are.class
ornamespace
orstruct
is found,sed
enters a loop.: loop
is a label, beginning of the loop.b loop
branches to the label, it's the end of the loop.t
which branches to the end of the script.t
will only work if the precedings
is successful.t
doesn't work, the script continues ton
which prints the current line and moves to the next.In other words both the outside and the inside of the loop print incoming lines, except only in the loop we are trying to do the substitution with
s
. A successful substitution leaves the loop. The tool will loop again if anotherclass
ornamespace
orstruct
is encountered.In yet other words this is exactly what you want (I think):
Notes:
class
(ornamespace
orstruct
) and the specific pattern.{
andspecific_text
because your test cases have spaces;$
instead of^
, because^
in your pattern is literal, it makes no sense (maybe you confused^
and$
anchors).Example input:
The output:
Altered lines:
class A { specific_text;
abc {specific_text;
(because ofnamespace
few lines before)