0

我有一大堆 C++ 源文件,我希望在其中插入一个简单的函数定义(大约 6 行)。该定义应立即出现在另一个函数定义之后。

使用这个问题的公认答案:sed match multiple lines 然后 append,我可以插入琐碎的函数定义,但我无法将其限定为适当类的成员。

测试代码:

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 tos'`

sed可以吗?

4

2 回答 2

2

这可能对您有用(GNU sed):

sed '/^.* \([^:]*::\)func1()$/{h;x;s//\nint \1func2()\n{\n    return 0;\n}/;x};//,/^}$/{/^}$/G}' file

这会查找函数定义,然后在保持空间 (HS) 中构建平凡函数。在遇到函数的末尾时,它会附加 HS。

于 2013-10-22T10:18:06.217 回答
1

反向引用只能引用同一表达式中的捕获。后面的分号!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
于 2013-10-22T01:46:23.643 回答