• Linux Shell | 解析xml节点


    01 xml文件

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

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


    02 多条命令解析xml节点

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

    [~]$ cat user.xml | grep name | sed 's/^.*<name>//g' | sed 's/</name>.*$//g'
    Toy
    [~]$ cat user.xml | grep name | sed 's/^.*<sex>//g' | sed 's/</sex>.*$//g'
    
    [~]$ cat user.xml | grep room | sed 's/^.*<room>//g' | sed 's/</room>.*$//g'
        <room/>
    

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

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


    03 一行 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文件
    

    04 小结

    我们在编写脚本时,需要解析文本文件时,尽量避免使用多命令和管道符的方式去解析,因为使用了管道符就会产生子进程,会加大了 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'
    

  • 相关阅读:
    《鱼嘤嘤小分队》第一次作业:项目选题
    第一次博客作业
    csp 201709-2 优先队列模拟
    csp 201403-2
    csp 201809-2 买菜
    JavaScript中伪协议
    修改placeholder的样式
    jQuery对象与DOM对象之间的转换方法
    a的样式
    Guid.NewGuid() 和 new Guid()的区别
  • 原文地址:https://www.cnblogs.com/xiaolincoding/p/11854011.html
Copyright © 2020-2023  润新知