在Shell脚本开发中,经常会遇到需要处理XML格式数据的场景,比如读取服务的XML配置文件、解析接口返回的XML响应结果等。对于结构简单的XML,我们不需要引入重量级的解析库,通过系统自带的基础工具就能完成解析工作。

方法一:使用grep和sed组合提取节点内容
对于标签层级简单、没有嵌套的XML,我们可以通过grep筛选目标行,再用sed提取标签内的内容。假设我们有如下简单的XML文件config.xml:
<config>
<app_name>test_app</app_name>
<port>8080</port>
<debug>true</debug>
</config>
如果我们要提取port节点的内容,可以使用下面的Shell脚本:
#!/bin/bash # 提取port节点内容 port=$(grep "<port>" config.xml | sed 's/<port>(.*)</port>/1/') echo "端口号是: $port"
这段脚本先通过grep找到包含<port>标签的行,再用sed的正则表达式匹配标签内的内容并替换输出,最终得到8080的结果。这种方法适合节点唯一、没有重复标签的简单场景。
方法二:使用awk按标签拆分数据
当XML中有多个同类型的节点时,使用awk可以更灵活地处理。比如下面的XML记录了多个用户信息:
<users>
<user>
<id>1</id>
<name>张三</name>
</user>
<user>
<id>2</id>
<name>李四</name>
</user>
</users>
我们可以用awk按<user>标签拆分,再提取每个用户的信息:
#!/bin/bash
# 使用awk解析多个user节点
awk '
BEGIN {
RS="</user>" # 设置记录分隔符为user节点结束标签
}
{
if (match($0, /<id>([0-9]+)</id>/, id_arr) && match($0, /<name>(.*)</name>/, name_arr)) {
print "用户ID: " id_arr[1] ", 用户名: " name_arr[1]
}
}
' config.xml
这里我们把</user>设为记录分隔符,这样每次处理一个完整的user节点,再通过match函数匹配id和name标签的内容,输出所有用户的信息。
方法三:使用xmlstarlet工具高效解析
如果系统安装了xmlstarlet工具,解析XML会更规范可靠,它支持XPath语法,能精准定位节点。首先安装xmlstarlet,CentOS系统可以用yum install xmlstarlet -y安装,Ubuntu系统用apt install xmlstarlet -y安装。
还是用最开始的config.xml文件,提取app_name节点内容的脚本如下:
#!/bin/bash # 使用xmlstarlet提取app_name节点内容 app_name=$(xmlstarlet sel -t -v "/config/app_name" config.xml) echo "应用名称是: $app_name"
如果要提取所有user节点的name内容,脚本可以这样写:
#!/bin/bash # 提取所有user的name xmlstarlet sel -t -m "/users/user" -v "name" -n config.xml
其中-t表示输出模板,-m是匹配节点,-v是输出节点值,-n是换行。这种方法支持复杂的XPath表达式,能处理有嵌套、重复节点的XML,是Shell脚本中解析XML的推荐方案。
不同方法的选择建议
如果XML结构非常简单,节点没有重复,用grep+sed组合最轻量;如果有多个同类型节点,用awk处理更灵活;如果XML结构稍复杂,或者需要长期维护的脚本,建议安装xmlstarlet工具,解析更稳定准确。实际使用时可以根据XML的复杂度和运行环境选择合适的方案。
Shell脚本XML解析xml_parser修改时间:2026-06-21 19:09:18