【问题标题】:sed multi-line replacement with line merging带行合并的 sed 多行替换
【发布时间】:2013-04-13 07:21:13
【问题描述】:

这可能有点复杂,但在这里: 假设我有一个如下所示的 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 个连续行
  • ... 之间的值并将其(加上一个空格字符)放在 之后的前一行
  • 删除第二行 ...

谢谢。

如果 sed 太多了,请提供其他建议,只要我可以从 mac shell 运行它。

【问题讨论】:

    标签: macos shell sed replace


    【解决方案1】:

    Ruby 将支持多行模式:

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

    【讨论】:

      【解决方案2】:

      不是最漂亮的解决方案,但它可以工作:-)

      $ 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'
      

      使用[^&lt;] 匹配括号内的任何内容

      【讨论】:

      • 非常感谢 Fredrik,但我忘了提到 1、2 等只是占位符文本。我实际上并不是说内容的内容是数字的。我们可以让它通用吗?处理标签之间的任何事情?我假设我只是将 ([0-9]\+) 更改为 (.*)?再次感谢:)
      • * 很可怕,它会消耗任何东西。这里的经典方法是使用[^&lt;]。查看更新
      • 你的“tr”技巧启发了我重做一些其他的规则。谢谢你:)
      猜你喜欢
      • 2010-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-03
      • 1970-01-01
      • 2022-01-19
      • 2011-01-23
      • 2021-02-18
      相关资源
      最近更新 更多