用线合并进行多线替换

时间:2013-04-19 19:44:23

标签: macos shell sed replace

这可能有点复杂,但在这里: 假设我有一个如下所示的XML:

<a>
<b>000</b>
<c>111</c>
<b>222</b>
<d>333</d>
<c>444</c>
</a>

我如何在mac上使用sed获得一个如下所示的XML:

<a>
<b>111 000</b>
<b>222</b>
<d>333</d>
<c>444</c>
</a>

基本上:

  • 匹配2个连续行,其形式为&lt; b&gt; ...&lt; / b&gt;然后是&lt; / c&gt; ...&lt; / c&gt;
  • 取&lt; c&gt; ...&lt; / c&gt;之间的值并且在&lt; b&gt;之后放置它(加上空格字符)在它之前的行
  • 删除第二行&lt; c&gt; ...&lt; / c&gt;

谢谢。

如果sed对此太多,请告知其他任何事情,只要我可以从mac shell运行它。

2 个答案:

答案 0 :(得分:1)

不是最美丽的解决方案,但它接缝工作: - )

$ tr '\n' @ < input | sed  's#<b>\([0-9]\+\)</b>@<c>\([0-9]\+\)</c>#<b>\2 \1</b#g' | tr @ '\n'

输出:

<a>
<b>111 000</b
<b>222</b>
<d>333</d>
<c>444</c>
</a>

或更一般:

$ tr '\n' @ < f1 | sed  's#<b>\([^<]*\)</b>@<c>\([^<]*\)</c>#<b>\2 \1</b#' | tr @ '\n'

使用[^<]来匹配括号中的任何内容

答案 1 :(得分:0)

Ruby会支持多行模式:

ruby -e 'print gets(nil).sub(/<b>([^\n]*)<\/b>\n<c>([^\n]*)<\/c>/m,"<b>\\2 \\1</b>")' file.txt