我想将<restApi>
和</restApi>
(包括restApi标记)之间的部分替换为另一个字符串:
...
<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>
...
"<sometag>stuff</sometag>"
的awk命令中我缺少什么?答案 0 :(得分: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
答案 1 :(得分:3)
使用sed或awk解析xml
的方法不正确。您应该使用带解析器的语言。在这里,我将提供一个perl及其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>
答案 2 :(得分:3)
解决问题的单行纯awk 解决方案
awk 'BEGIN {A = 1};/<restApi>/{A=0; print "<sometag>stuff</sometag>"};/.*/ { if ( A == 1) print $0};/<\/restApi>/{A=1}; ' file.xml
如果你经常处理xml转换,你应该考虑使用xslt,正如其他人所说的那样
答案 3 :(得分:0)
如果你将awk输出传输到uniq
,你可能会得到你想要的。