用sed编辑一行

时间:2012-09-21 22:09:27

标签: shell unix

我的输入包含使用typedef定义的结构。 我后来用它来初始化我的main函数中的变量。

例如:

typedef struct {
   int numer;
   int denom;
} Rational;

int main()
{
Rational half, *newf = malloc(sizeof(Rational));

half = (Rational){ 1, 2 };
*newf = (Rational){ 2, 3 };
}

这是我想要做的: 我想将两个初始化行转换为函数调用。

例如:

half = (Rational){ 1, 2 };

应该变成:

init_Rational( &half,  1, 2  );

*newf = (Rational){ 2, 3 };

应该变成

init_Rational( newf,  2, 3  );

诀窍是要记住Rational之前被定义为结构,并用函数调用替换初始化。它不必被称为Rational,它可以是任何名称。

一旦识别出声明是struct typedef,它就应该执行以下操作,如上所示。

转到:

something = (someStructName){ data1, data2, data3.. };

init_someStructName( &something, data1, data2, data3.. );

或指示......转:

*something = (someStructName){ data1, data2, data3.. };

init_someStructName( something, data1, data2, data3.. );

有人可以帮助我吗?谢谢!

2 个答案:

答案 0 :(得分:1)

这是一个非常棘手的问题,因为需要动态检测结构名称意味着您无法提前编写整个正则表达式。

这是一个可能的解决方案,假设您的文件名是foo.c:

sed -n '/^typedef struct/,/^}/{/^}/{s/.* \(.*\);/\1/p}}' foo.c | xargs -I {} sed -i -e 's/^\(\s*\)\*\(\w*\) = ('{}'){\(.*\)};/\1init_'{}'( \2,\3);/' -e 's/^\(\s*\)\(\w*\) = ('{}'){\(.*\)};/\1init_'{}'( \&\2,\3);/' foo.c

这将通过sed传递一行单独打印每个结构名称,然后使用xargs为每个结构构造一个额外的sed命令来执行替换在文件上。

如果您的sed版本不支持\s\w个快捷方式,则可以使用[ \t]代替\s[_a-zA-Z0-9]而不是\w

答案 1 :(得分:0)

几乎不可读!

sed -e 's/\(\**[a-zA-Z_][a-zA-Z_0-9]*\) *= *( *\([a-zA-Z_][a-zA-Z_0-9]*\) *) *{\([^}]*\)} *;/init_\2(\&\1,\3);/'

注意:这是一行 注2:我假设可能只有空格作为可能的分隔符(没有TAB) 注3:表单“*x”保持不变,因为它已转换为&*x,这是正确的。我假设“*”和标识符之间没有空格;