2014-01-16 65 views
1

我想替换下面的部分<restApi></restApi>(包括RESTAPI标记)与另一个字符串之间:替换AWK的XML文件的部分或sed的

... 
    <restApi> 
    <baseUrl>https://domain.com/nexus</baseUrl> 
    <forceBaseUrl>true</forceBaseUrl> 
    <uiTimeout>60000</uiTimeout> 
    </restApi> 
... 

使用AWK,我使用下面的命令做替换:

awk '/<restApi>/,/<\/restApi>/ {sub(/.*/,"<sometag>stuff</sometag>")}1' file.xml 

的问题是,AWK替换替换字符串,所以我得到这个输出的每一行:

... 
<sometag>stuff</sometag> 
<sometag>stuff</sometag> 
<sometag>stuff</sometag> 
<sometag>stuff</sometag> 
<sometag>stuff</sometag> 
... 
  • 我在awk命令中缺少的结果中只有一个"<sometag>stuff</sometag>"
  • 如何用sed代替它?
  • 更换期间间距/标签丢失。我该如何保存它?
+0

'。*'表示线上的所有字符,所以每一行都是变化的。什么是预期产出? – Jotne

+5

错误第一:XML不是字符串。你不应该对XML进行字符串处理。使用XML-aware工具,如xsltproc。 – Tomalak

+0

@Jotne 预计产量为 ... 东西 ... – PapelPincel

回答

3

单行纯awk的解决方案,如果你经常使用XML转换处理,解决你的问题

awk 'BEGIN {A = 1};/<restApi>/{A=0; print "<sometag>stuff</sometag>"};/.*/ { if (A == 1) print $0};/<\/restApi>/{A=1}; ' file.xml 

你应该考虑使用xslt,正如别人所说的

0

如果你将你的awk输出流入uniq,你可能会得到你想要的。

3

这是一个不正确的方法来解析xml。你应该在解析器中使用一种语言。在这里,我将提供及其XML::Twig模块的示例:

假设以下输入文件:

<root> 
    <restApi> 
    <baseUrl>https://domain.com/nexus</baseUrl> 
    <forceBaseUrl>true</forceBaseUrl> 
    <uiTimeout>60000</uiTimeout> 
    </restApi> 
    <t>data</t> 
    <restApi> 
    <baseUrl>https://domain.com/nexus</baseUrl> 
    <forceBaseUrl>true</forceBaseUrl> 
    <uiTimeout>60000</uiTimeout> 
    </restApi> 
</root> 

而继perl脚本:

#!/usr/bin/env perl 

use warnings; 
use strict; 
use XML::Twig; 

XML::Twig->new(
    twig_handlers => { 
     'restApi' => sub { 
      my $elem = XML::Twig::Elt->new('sometag', 'stuff'); 
      $elem->replace($_); 
     }, 
    }, 
    pretty_print => 'indented', 
)->parsefile(shift)->print; 

运行它想:

perl script.pl xmlfile 

这会产生:

<root> 
    <sometag>stuff</sometag> 
    <t>data</t> 
    <sometag>stuff</sometag> 
</root> 
+1

+1为理智的方法加上证明做正确的事情并不困难。 – Tomalak

4

正如我在上面的评论中指出的那样,使用XML认识工具。

XSLT是一个,所以这里是一个简单的样式表,用于替换<restApi>元素,同时保留其他所有元素,包括空格和制表符。

<!-- newRestApi.xsl --> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="restApi"> 
    <sometag>stuff</sometag> 
    </xsl:template> 
</xsl:stylesheet> 

xsltproc使用是死简单:

xsltproc newRestApi.xsl input.xml > output.html