我有
<funcprototype>
<funcdef>void <function>foo</function></funcdef>
<paramdef>int <parameter>target</parameter></paramdef>
<paramdef>char <parameter>name</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>void <function>foo2</function></funcdef>
<paramdef>int <parameter>target2</parameter></paramdef>
<paramdef>char <parameter>name2</parameter></paramdef>
</funcprototype>
我需要得到:void foo( int tagret char name)
void foo2( int tagre2 char name2)
使用sed我可以做
void foo(
int target
char name
)
void foo2(
int target2
char name2
)
我使用此命令
awk "/\<funcprototype\>/,/\<\/funcprototype\>/ { print }" foo.xml | sed 's/^[ ^t]*//;s/[ ^]*$//'|sed -e '/^$/d'|sed 's/ //g'| sed 's/<funcprototype>//;s/<funcdef>//;s/<function>/ /;s/<\/function><\/funcdef>/(/;s/<paramdef>//;s/<parameter>/ /;s/<\/parameter><\/paramdef>//;s/<\/funcprototype>/)/;'
我怎样才能做我想做的事?
答案 0 :(得分:0)
在sed中处理像XML这样的文件格式总是很糟糕,所以“正确”的解决方案在很大程度上取决于你想要的输入除外。以下sed脚本至少适用于您提供的示例数据:
:loop
/<\/funcprototype>/ ! { N; b loop; }
s/\n/ /g;
s/<\/\?\(funcdef\|parameter\|function\|funcprototype\)>//g;
s/<paramdef>/(/g;
s/<\/paramdef>/)/g;
s/) *(/, /g;
s/ */ /g;
s/^ //;
s/ $//;
s/ (/(/;
有趣的是前两行中的:loop
部分::loop
行定义标签,第二行将输入的下一行追加到缓冲区并跳回标签直到缓冲区包含结束</funcprototype>
标记。因此,在这两个命令之后,整个多行<funcprototype> .. </funcprototype>
块在缓冲区中(行\n
个字符分隔)。然后使用第3行中的s/\n/ /g
命令将换行符替换为空格。