我有一大堆 C++ 源文件,我希望在其中插入一个简单的函数定义(大约 6 行)。该定义应立即出现在另一个函数定义之后。
使用此问题的公认答案:sed 匹配多行然后追加,我可以插入简单的函数定义,但我无法将其范围限定为适当类的成员。
测试代码:
void object::func1()
{
std::cout << "func1" << std::endl;
}
插入非成员函数:
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;
}
尝试对类名进行分组并使用反向引用,如下所示会导致
1::func2
而不是 object::func2
。
sed '/\([[:alnum:]]\+\)::func1()$/,/^}/!b;/^}/a \\nint \1::func2()\n{\n\ \ \ \ return 0;\n}' testcode.cc
如果我使用替代命令而不是附加命令,它会起作用,但是替代命令被
/,/
破坏,导致:
sed: -e expression #1, char 33: unknown option to
'`
在 sed 中可以吗?
这可能对你有用(GNU sed):
sed '/^.* \([^:]*::\)func1()$/{h;x;s//\nint \1func2()\n{\n return 0;\n}/;x};//,/^}$/{/^}$/G}' file
这会查找函数定义,然后在保留空间(HS)中构建简单函数。在遇到函数末尾时,它会附加 HS。
反向引用只能引用同一表达式内的捕获。
!b
后面的分号结束第一个表达式。保留空间可以将字符串从一个表达式传递到另一个表达式。
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 一次将一行读入模式空间,其中运行诸如
s///
之类的命令。
可以将线条放在保留空间中,稍后将其检索回模式空间。
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