sed需要像追加的反向引用

时间:2013-10-21 22:50:45

标签: regex sed

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

使用这个问题的接受答案:sed match multiple lines and then 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

如果我使用的是substitute命令而不是append命令,那么它会起作用,但是/,/会破坏substitute命令,导致:

sed: -e expression #1, char 33: unknown option to s'`

sed可以吗?

2 个答案:

答案 0 :(得分:2)

这可能适合你(GNU sed):

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

这将查找函数定义,然后在保留空间(HS)中构建普通函数。在遇到函数结束时,它会附加HS。

答案 1 :(得分: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