Linux Shell 解析xml节点的值

xml文件

# user.xml
<user>
    <name>Toy</name>
    <sex>man</sex>
    <room/>
</user>

其中第 5 行的<room/> xml 节点是空节点,是比较特殊的格式。

多条命令解析xml节点

采用多条命令和管道符也可以解析xml节点,方式如下:

# cat user.xml | grep name | sed 's/^.*<name>//g' | sed 's/<\/name>.*$//g'
Toy
# cat user.xml | grep sex | sed 's/^.*<sex>//g' | sed 's/<\/sex>.*$//g'
man
# cat user.xml | grep room | sed 's/^.*<room>//g' | sed 's/<\/room>.*$//g'
    <room/>

上面的方式无法解析<room/>这种特殊格式的 xml 节点,虽然用多个命令和管道符是可以实现解析正常格式的xml节点的值,但是过多的管道符是会降低执行效率的。

因为管道符是会为连接的命令产生子进程,从而加大CPU的开销。

一行 awk 命令解析xml节点

awk 命令解析所有特殊的 xml 节点的值,只需要一行命:

$ awk  '/<\/*name\/*>/{gsub(/[[:space:]]*<\/*name\/*>/,"");print $0}' user.xml
Toy
$ awk  '/<\/*sex\/*>/{gsub(/[[:space:]]*<\/*sex\/*>/,"");print $0}' user.xml
man
$ awk  '/<\/*room\/*>/{gsub(/[[:space:]]*<\/*room\/*>/,"");print $0}' user.xml

上面的awk方式可以兼容所有特殊的 xml 节点,并且只需要一条命令就能解析出 xml 的值。简单说明下命令的意思:

  • awk '/匹配的字符串/{print $0}'表示在文本中,找到匹配的字符串所在的行记录,可以替代grep "匹配的字符串"
  • gsub(/匹配的字符串/,"")是 awk 内部的函数,表示将匹配到的字符串替换成"",也就是替换成空字符串,可以替代sed 's/匹配的字符串//g'
  • </*name/*>中的*号是正则表达式,*号表示可以重复前面字符 0 个或多个,所以</*name/*>可以间接的表示<name></name><name/>
  • [[:space:]]表示匹配空格、制表格等空白符,[[:space:]]*表示匹配空白字符0个或多个
  • $0表示取记录的所有记录

所以,awk 解析 xml 节点的命令小结成如下:

awk '/<\/*节点名字\/*>/{gsub(/[[:space:]]*<\/*节点名字\/*>/,"");print $0}' xml文件

小结

在编写脚本需要解析文本文件时,尽量避免使用多命令和管道符的方式去解析,因为使用了管道符就会产生子进程,会加大了 CPU 的开销。

大部分情况下只需要一条 awk 命令就完成解析的工作,相比较起多命令和管道符的方式效率会更高,并且CPU开销小。

通过以上的两个解析xml节点的案例,我们可以总结出:

awk '/匹配的字符串/{print $0}' 可以替代 grep "匹配的字符串"
awk  '{gsub(/匹配的字符串/,"");print $0}' 可以替代 sed 's/匹配的字符串/""/g'

awk '/匹配的字符串/{gsub(/匹配的字符串/,"");print $0}' <xml文件> 
可以替代
cat <xml文件> | grep "匹配的字符串" | sed 's/匹配的字符串/""/g'

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/24/linux-shell-parse-values-of-xml-nodes/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Linux Shell 解析xml节点的值
xml文件 # user.xml <user> <name>Toy</name> <sex>man</sex> <room/> </user> 其中第 5 行的<ro……
<<上一篇
下一篇>>
文章目录
关闭
目 录