0

我的输入中有几行我正在初始化结构。例如:

head = (struct node) {5, NULL};

我需要将这些行转换为以下内容:

init_node( &head, 5, NULL);

那就是......任何时候我在输入文件中看到以下行:

something = (struct something2){ something3, something4};

我需要将其转换为:

init_something2( &something1, something3, something4);

我想我需要在这里使用 sed 功能。有人可以帮忙吗??谢谢

4

4 回答 4

1

Sed 可能也可以工作,但这里有一些适用于 perl 的东西:

perl -pe 's|(.*) = \(struct node\) {(.*), (.*)};|init_node( &\1, \2, \3);|'

请注意,我在匹配中使用括号表达式捕获每个“某物”,然后在替换中使用 \1、\2 等检索它们。这是您真正需要知道的唯一部分。希望您能弄清楚如何使任一表达式足够灵活以适合您的实际数据(除非您奇迹般地对每一行都有一致的样式)。

于 2012-09-20T22:12:31.427 回答
1

我会做:

sed -e 's/\s*\([_a-zA-Z][0-9a-zA-Z_]*\)\s*=\s*(\s*struct\s*\([_a-zA-Z][0-9a-zA-Z_]*\)\s*)\s*{\s*\([^}]*\)}\s*;/init_\2( \&\1, \3);/' -i you_file.c

解释疯狂的正则表达式:

1) \s* 跳过零个或多个空格(因此它变得更加灵活)。

其次,我们通过使用 ( ) 获取一个 C 标识符(如果我错了,请有人纠正我)可以以字母或下划线中的字符开头,并且可以包含字母数字字符和下划线([ a-zA-Z ][0-9a-zA-Z ]*)。

第三次跳过等号后跟零个或多个空格,然后跳过左括号后跟空格,然后跳过结构后跟空格

第四:抓取另一个标识符

第五:跳过一个由零个或多个空格包围的右括号,然后是一个左括号,后跟空格

第六:在右括号之前抓取任何东西(注意这一点!你不能在代码中包含包含括号的表达式)

第七:跳过右括号,然后是空格,然后是分号

最后:重新排列抓取的内容 =)

编辑:注意“&”必须被转义:“\&”。如果不是,sed 将用整个匹配替换它

EDIT2:感谢 Jonathan 对如何包含任意数量的初始化程序(带逗号)的观察

希望这可以帮助,

贾尼托

于 2012-09-20T22:19:07.160 回答
0

正则表达式在这里是你的朋友(假设你的输入是一致的格式)。

该表达式\([a-zA-Z]*\) = (struct \([a-zA-Z]*\)) {\([a-zA-Z0-9, ]*\)};应该为您的输入字符串建模。使用这些捕获组,表达式init_\2( \&\1, \3);应该生成您想要的输出字符串。将这些放在一起,以下sed命令应该可以满足您的需要:

sed -e 's/\([a-zA-Z]*\) = (struct \([a-zA-Z]*\)) {\([a-zA-Z0-9, ]*\)};/init_\2( \&\1, \3);/g'

这假定您的struct和变量名称仅由大写和小写字母组成(我保持简单,以防止示例变得太宽而无法容纳页面)。如果它们包含其他字符,则需要相应地调整表达式。

于 2012-09-20T22:12:58.123 回答
0

更一般的 sed 匹配:

sed -e 's/\([a-zA-Z0-9]*\)\s*=\s*(\s*struct\s\([a-zA-Z0-9]*\)\s*)\s*{\s*\([a-zA-Z0-9]*\)\s*,\s*\([a-zA-Z0-9]*\)\s*}\s*;/init_\2( \&\1, \3, \4);/g'

这将匹配如下表达式:

  • something=( struct something2) {something3,something4};
  • something = (struct something2) { something3 , something4 };

等等

于 2012-09-20T22:16:12.837 回答