Issue
I have a whole bunch of C++ source files within which I wish to insert a trivial function definition (around 6 lines). The definition should appear immediately after another function definition.
Using the accepted answer to this question: sed match multiple lines and then append, I can insert the trivial function definition, but I am unable to scope it as a member of the appropriate class.
Test code:
void object::func1()
{
std::cout << "func1" << std::endl;
}
Insertion of non-member function:
james@scrapyard:~/Projects$ sed '/func1()$/,/^}/!b;/^}/a \\nint func2()\n{\n\ \ \ \ return 0;\n}' func1.cc
void object::func1()
{
std::cout << "func1" << std::endl;
}
int 1::func2()
{
return 0;
}
Attempting to group the class name and use a back reference as below results in 1::func2
rather than object::func2
.
sed '/\([[:alnum:]]\+\)::func1()$/,/^}/!b;/^}/a \\nint \1::func2()\n{\n\ \ \ \ return 0;\n}' testcode.cc
If I were using the substitute command instead of the append command it would work, but the substitute command is broken by the /,/
resulting in:
sed: -e expression #1, char 33: unknown option to
s'`
Is it possible in sed?
Solution
A backreference may only refer to a capture within the same expression. The semicolon after !b
ends the first expression. The hold space can carry a string from one expression to another.
sed '/\w\+::func1()$/,/^}/!b;/\w\+::func1()$/{h;s/^\w*\s\+\(\w\+\)::func1()$/\1/;x};/^}/ {g;s/.*/}\n\nint &::func2()\n{\n\ \ \ \ return 0;\n}/}' testcode.cc
Sed reads a line at a time into the pattern space, where commands like s///
operate.
Lines can be set aside in the hold space and retrieved back into the pattern space later.
sed '
/\w\+::func1()$/,/^}/!b # Ignore lines outside the target function.
/\w\+::func1()$/ { # On the line declaring the function,
h # save that line to the hold space;
s/^\w*\s\+\(\w\+\)::func1()$/\1/ # replace the function with its class name;
x # save the class name and restore the function declaration.
}
/^}/ { # at the end of the target function
g # retrieve the class name
# substitue the class name into the new function
s/.*/}\n\nint &::func2()\n{\n\ \ \ \ return 0;\n}/
}
' testcode.cc
Answered By - traybold Answer Checked By - Timothy Miller (WPSolving Admin)