使用sed将一个命名空间替换为两个

时间:2012-05-21 23:10:37

标签: regex sed

我有以下代码布局:

#ifndef _file_h_
#define _file_h_

namespace FooBar
{
    // code
}

#endif

我希望通过sed运行它并将FooBar名称空间转换为Foo :: Bar并添加右括号

#ifndef _file_h_
#define _file_h_

namespace Foo { namespace Bar {

// code

}}

#endif

我承认我的正规表达知识在最好的时候都很差。

我认为下面的命令接近于实现我正在寻找的东西,但我得到的一些语法错误。有人可以帮忙吗?

cat file.h  | sed -e 's/(.*)namespace FooBar[\s\n]{(.*)}/\1namesapce Foo \{ namespace Bar \{\2\}\}/g' | less

2 个答案:

答案 0 :(得分:1)

希望你的头文件的格式总是像你已经显示的那样(命名空间在它自己的行上,在行的开头打开/关闭括号等)。

如果是这样,您无需担心在此捕获。尝试:

sed -e 's/namespace FooBar/namespace Foo { namespace Bar/g; s/^}/}}/g;' file.h > file2.h

如果没有,请将@ sarnold的评论铭记于心 - 这将很难。

答案 1 :(得分:1)

知道最后一个大括号将永远是文件中的最后一个大括号,这给了我一个可能有效的想法:

首先,窃取Rob的第一个正则表达式:

sed -ie 's/namespace FooBar/namespace Foo { namespace Bar/g;' file.h

接下来,最后一个大括号的新正则表达式:

perl -pi -e 's/^}$(.*?)\z/}}\1/ms' file.h

我为第二个命令切换到Perl,所以我可以使用它不那么贪婪的*?运算符,^$\z断言,以及{{ 1}}修饰符(用于获得友好的多行匹配)。

这两个命令组合在您的示例文件上进行了以下更改:

/ms

这个非常脆弱 - 一个完整的C ++语言解析器会更强大,但肯定不容易写。我希望剩下的东西很容易用手来处理。