Bash脚本解析XML时无法分组关联各属性集的解决方案咨询
按pattern节点分组拼接XML字段方案
不推荐用纯正则/awk硬解析XML,XML的标签嵌套、换行、缩进格式没有强制规范,硬写的正则逻辑很容易因为XML格式微调直接失效,优先用专门的XML命令行处理工具最稳妥。
方案1:xmlstarlet(推荐,生产可用)
xmlstarlet是专门面向命令行的XML处理工具,会按XML DOM结构解析节点,完全不受缩进、换行变动影响。
- 先安装工具:
- Debian/Ubuntu 系列:
sudo apt install xmlstarlet - RHEL/Fedora/CentOS 系列:
sudo dnf install xmlstarlet
- Debian/Ubuntu 系列:
- 直接输出拼接结果的命令:
xmlstarlet sel -t -m '//pattern' -v 'name' -o '-' -v 'code' -o '-' -v 'format' -n sample.xml
参数说明:
sel:进入XML查询选择模式-t:定义输出模板-m '//pattern':匹配文档中所有层级的<pattern>节点-v 'xxx':提取当前节点下对应标签的值-o '-':输出连接符短横线-n:每个pattern的拼接结果输出完后换行如果需要把结果存入bash数组,用如下写法:
#!/bin/bash pattern_arr=() while IFS= read -r res_line; do pattern_arr+=("$res_line") done < <(xmlstarlet sel -t -m '//pattern' -v 'name' -o '-' -v 'code' -o '-' -v 'format' -n sample.xml) # 测试输出数组内容 printf '%s\n' "${pattern_arr[@]}"
执行后输出结果为:
ABC-1234-txt XYZ-7799-csv
方案2:awk硬解析(仅适配当前固定XML格式,不推荐长期用)
如果你的运行环境实在无法安装xmlstarlet,可以用下面的awk脚本,逻辑是按pattern标签做块标记,块内分别提取三个字段值,碰到pattern闭标签时拼接输出,能维持分组对应关系:
awk ' /<pattern>/ { in_block = 1 name = code = fmt = "" } in_block && /<name>/ { match($0, /<name>([^<]+)<\/name>/, m) name = m[1] } in_block && /<code>/ { match($0, /<code>([^<]+)<\/code>/, m) code = m[1] } in_block && /<format>/ { match($0, /<format>([^<]+)<\/format>/, m) fmt = m[1] } /<\/pattern>/ { print name "-" code "-" fmt in_block = 0 } ' sample.xml
注意:这个方案只适配你给出的「每个标签单独占一行、标签值不含嵌套标签」的固定格式,只要XML调整换行、缩进或者嵌套结构,脚本就可能解析失败。
内容的提问来源于stack exchange,提问作者piks
相关产品推荐
相关产品推荐

