用sed转换字符串

时间:2012-09-20 21:56:57

标签: shell unix

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

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

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

init_node( &head, 5, NULL);

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

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

我需要将其转换为:

init_something2( &something1, something3, something4);

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

4 个答案:

答案 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 };