sed 需要类似追加的反向引用之类的东西

问题描述 投票:0回答:3

我有一大堆 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 中可以吗?

regex sed
3个回答
2
投票

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

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

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


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

0
投票

问题的核心似乎可以通过手册中的这一行来回答:

反向引用和子表达式在两种情况下使用: 正则表达式搜索模式,并在替换部分 s命令

也就是说,反向引用与追加 (

a
) 命令不兼容。

© www.soinside.com 2019 - 2024. All rights reserved.