我有一个巨大的XML文件,需要更改我知道的一行以上的几百行。
<errorCode>4544</errorCode>
<severity>4</severity>
<modelDescription>Licensing: Invalid license</modelDescription>
我想要&#34;许可:无效的许可证&#34;并改变&#34; 4&#34;高于它或任何其他数字。
我正在尝试做类似的事情:
sed -i '/Invalid license/{n;s/4/6/;}' file
但它不起作用。任何建议我如何grep一个模式,然后更改它上面的值?
答案 0 :(得分:0)
您可以存储上一行并检查当前行是否与您的模式匹配。如果是这样,请修改上一行并打印,否则打印。请参阅以下内容:
while IFS= read line
do
echo $line | grep "<severity>[0-9]</severity>" > /dev/null && {
sev=$line
} || {
echo $line | grep "Invalid license" > /dev/null && {
echo $sev | sed "s/4/5/"
} || {
if [ ! -z $sev ]; then echo $sev; fi
}
sev=""
echo $line
}
done < file
答案 1 :(得分:0)
不要将SED用于XML解析,因为它不是为处理XML语法而设计的,而在SED中编写XML解析器是一项艰巨的任务。此外,有许多有用的工具正是为了这个目的。
考虑这个XML:
<root>
<item>
<errorCode>4000</errorCode>
<severity>2</severity>
<modelDescription>Some error</modelDescription>
</item>
<item>
<errorCode>4544</errorCode>
<severity>4</severity>
<modelDescription>Licensing: Invalid license</modelDescription>
</item>
</root>
您可以使用xmlstarlet
轻松修改severity
值:
xmlstarlet ed -u '//item[severity = 4
and modelDescription = "Licensing: Invalid license"]/severity' \
-v 100 file.xml
该命令通过将原始值(-u
)替换为severity
来更新4
元素100
元素的值。 XPath表达式选择severity
个元素的item
个元素,其中severity
子元素值为4
,modelDescription
子元素值为Licensing: Invalid license
。
结果打印到标准输出。要就地编辑文件,请使用--inplace
选项:xmlstarlet ed --inplace -u ...
。
输出
<?xml version="1.0"?>
<root>
<item>
<errorCode>4000</errorCode>
<severity>2</severity>
<modelDescription>Some error</modelDescription>
</item>
<item>
<errorCode>4544</errorCode>
<severity>100</severity>
<modelDescription>Licensing: Invalid license</modelDescription>
</item>
</root>
答案 2 :(得分:0)
这是一个流式XSLT 3.0转换,可以完成这项工作,假设您显示的元素包含在item元素中:
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:mode name="c" streamable="no" on-no-match="shallow-copy"/>
<xsl:template match="item">
<xsl:apply-templates select="copy-of(.)" mode="c"/>
</xsl:template>
<xsl:template mode="c"
match="severity[following-sibling::modelDescription=
'Licensing: Invalid license']">
<severity>6</severity>
</xsl:template>
</xsl:transform>
必须在处理之前复制item元素,因为您希望在处理severity元素时“向前看”,而在流模式下无法完成。
答案 3 :(得分:0)
这可能会帮助
sed -i.bak '/Invalid license/!{x;1!p;d;};x;s/4/6' <file path>