如何在Linux Bash中用sed/awk/xmllint替换指定XML标签而非值
问题
现有一个包含如下内容的XML文件:
<Extrinsic name="CommodityVendor">1234567</Extrinsic> <Extrinsic name="buyerVatID">1122334455</Extrinsic> <Extrinsic name="supplierVatID">S9876543</Extrinsic>
需要将其中对应buyerVatID的<Extrinsic>标签替换为<ExtrinsicB>,输出结果如下:
<Extrinsic name="CommodityVendor">1234567</Extrinsic> <ExtrinsicB name="buyerVatID">1122334455</ExtrinsicB> <Extrinsic name="supplierVatID">S9876543</Extrinsic>
请问如何在Linux Bash环境下使用sed、awk或xmllint工具实现这一需求?
解决方案
使用sed实现
sed适合快速文本替换,通过匹配特定行的属性进行精准替换:
# 直接输出处理后的结果 sed -e '/name="buyerVatID"/ s/Extrinsic/ExtrinsicB/g' input.xml # 直接修改原文件并备份原文件为input.xml.bak sed -i.bak -e '/name="buyerVatID"/ s/Extrinsic/ExtrinsicB/g' input.xml
解释:
/name="buyerVatID"/:匹配包含目标属性的行s/Extrinsic/ExtrinsicB/g:在匹配行内全局替换标签名
使用awk实现
awk可灵活处理行内容,针对目标行执行替换操作:
awk '/name="buyerVatID"/ {gsub(/Extrinsic/, "ExtrinsicB")} 1' input.xml
解释:
/name="buyerVatID"/:定位到目标行gsub(/Extrinsic/, "ExtrinsicB"):在该行全局替换标签字符串1:输出所有行(包含处理后的目标行和未修改的其他行)
使用xmllint实现(XML专用推荐方案)
若XML结构复杂,文本工具可能存在匹配风险,xmllint结合XSLT的方式更可靠:
# 创建XSLT转换文件convert.xsl cat > convert.xsl << 'EOF' <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="Extrinsic[@name='buyerVatID']"> <ExtrinsicB> <xsl:apply-templates select="@*|node()"/> </ExtrinsicB> </xsl:template> </xsl:stylesheet> EOF # 执行XML转换 xmllint --xinclude --style convert.xsl input.xml
解释:
- 第一个模板为默认复制规则,保留所有未匹配的XML内容
- 第二个模板精准匹配
name="buyerVatID"的Extrinsic元素,将其替换为ExtrinsicB,同时保留原元素的属性和内部内容
内容的提问来源于stack exchange,提问作者user3152289
相关产品推荐
相关产品推荐

