我在输入中有几行我正在初始化结构。例如:
head = (struct node) {5, NULL};
我需要将这些行转换为以下内容:
init_node( &head, 5, NULL);
那是......任何时候我在输入文件中看到以下行:
something = (struct something2){ something3, something4};
我需要将其转换为:
init_something2( &something1, something3, something4);
我想我需要在这里使用sed功能。 有人可以帮忙吗? 感谢
答案 0 :(得分:1)
Sed也可能会起作用,但这里的东西适用于perl:
perl -pe 's|(.*) = \(struct node\) {(.*), (.*)};|init_node( &\1, \2, \3);|'
请注意,我在匹配中使用括号表达式捕获每个“某事物”,然后在替换中使用\ 1,\ 2等检索它们。这是你真正需要知道的唯一部分。希望您能弄清楚如何使表达式足够灵活以适合您的实际数据(除非您奇迹般地为每一行提供一致的样式)。
答案 1 :(得分: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
解释Crazy RegExp:
1)\ s *跳过零个或多个空格(因此它变得更加灵活)。
其次我们使用()一个C标识符来抓取(如果我错了,请有人纠正我)可以从字母表或下划线开始,并且可以包含字母数字字符和下划线([ A-ZA-Z] [0-9A-ZA-Z ] *)。
第三个跳过一个等号然后是零或多个空格,然后跳过一个左括号后跟空格,然后是一个结构后跟空格
第四:抓住另一个标识符
第五:跳过由零个或多个空格包围的近括号,然后是一个空括号后跟空格
第六:在关闭括号之前抓住任何东西(小心这个!你不能在代码中包含一个包含括号的表达式)
第七:跳过关闭括号,然后是空格,然后是分号
最后:重新安排抓取的内容=)
编辑:请注意“&”必须逃脱:“\&”。如果不是,那么sed会将其替换为整场比赛
EDIT2:感谢Jonathan关于如何包含任意数量的初始化器(带逗号)的观察
希望这有帮助,
Janito
答案 2 :(得分: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
和变量名只包含大写和小写字母(我保持简单,试图阻止该示例对于页面变得太宽)。如果它们包含其他字符,则需要相应地调整表达式。
答案 3 :(得分: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 };
等