【问题标题】:Merge multiple lines with condition合并多行条件
【发布时间】:2017-04-12 18:52:13
【问题描述】:

我有一个格式为 xml 的文件

<movie>
<title>Title</title>
<originaltitle>Original Title</originaltitle>
<id>ID1234</id>
</movie>

我使用sed合并原标题和id标签失败,如下:

<movie>
<title>Title</title>
<originaltitle>ID1234 - Original Title</originaltitle>
</movie>

如何将匹配保存在 id 上,并在修改标题标签时在其他地方重复使用?请注意,id 标签是可选的,因此并不总是存在,在这种情况下,原始标题应该保持不变。我可以编写一个脚本来遍历文件标签并实现相同的目的,但我认为有人可能会为此提出一个优雅的 sed 解决方案。任何想法 ?我可以单独匹配每个条目,但我不知道如何保存一个以供以后使用。到目前为止我得到了这个,它不起作用

sed '/<id>(.*)<\/id>/ {s/<sorttitle>(.*)<\/sorttitle>/<sorttitle>\1 - \2<\/sorttitle>/}' movie.nfo

【问题讨论】:

  • 正如其他人所指出的,使用面向行的工具来处理 XML 并不是一个好主意。此外,将 title 和 id 结合起来似乎是一个非常糟糕的主意。

标签: regex awk sed


【解决方案1】:

不要使用 sed 处理 XML 文件,使用 XML 感知工具。

我目前维护xsh,这使您的任务非常简单:

open file.xml ;
insert text " - " prepend /movie/originaltitle ;
move /movie/id/text() prepend /movie/originaltitle ;
delete /movie/id ;
save :b ;

【讨论】:

    【解决方案2】:

    在 awk 中。读取&lt;originaltitle&gt;&lt;id&gt; 后,将它们合并并打印。标签和结束标签应该在同一条记录中。

    $ awk '/<originaltitle>/ { i++; ot=$0; next }
                      /<id>/ { i++; gsub(/<\/?id>/,""); id=$0; next } 
                        i==2 { i=""; sub(/<originaltitle>/,"&" id " - ",ot); print ot } 
           1' file
    <movie>
    <title>Title</title>
    <originaltitle>ID1234 - Original Title</originaltitle>
    </movie>
    

    【讨论】:

      【解决方案3】:

      如果你更喜欢 (gnu)sed,那么 以下命令解决了这个问题:

      sed -e 'N;' \
          -e '/<\/id>$/ s/<originaltitle>\(.*\)<\/originaltitle>\n<id>\(.*\)<\/id>/<originaltitle>\2 - \1<\originaltitle>/;' movie.nfo
      

      第一个命令让您始终读取 2 行。

      当当前模式空间的结尾包含 时,总是会触发第二个命令。现在您只需要重新排列标签并翻转 id 和 originaltitle 值(通过 s 命令)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-03
        • 2020-03-10
        • 2021-11-21
        • 1970-01-01
        • 2018-02-19
        • 2022-11-14
        • 2017-03-08
        • 1970-01-01
        相关资源
        最近更新 更多