合并具有条件的多行

时间:2016-11-28 22:29:32

标签: regex awk sed

我有一个格式为

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

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

3 个答案:

答案 0 :(得分:0)

请勿使用sed处理XML文件,请使用支持XML的工具。

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

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

答案 1 :(得分:0)

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

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

第一个命令可以让你总是读两行。

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

答案 2 :(得分:0)

在awk中。读完<originaltitle><id>后,将它们组合并打印。标签和结束标签应该在同一记录中。

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