# user.xml <user> <name>Toy</name> <sex>man</sex> <room/> </user>
其中第 5 行的<room/>
xml 节点是空节点,是比较特殊的格式。正则表达式
采用多条命令和管道符也能够解析xml节点,方式以下:bash
[~]$ 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的开销。spa
awk 命令解析全部特殊的 xml 节点的值,只须要一行命:code
[~]$ 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 的值。xml
简单说明下命令的意思:进程
awk '/匹配的字符串/{print $0}'
表示在文本中,找到匹配的字符串所在的行记录,能够替代grep "匹配的字符串"
字符串
gsub(/匹配的字符串/,"")
是 awk 内部的函数,表示将匹配到的字符串替换成""
,也就是替换成空字符串,能够替代 sed 's/匹配的字符串//g'
</*name/*>
中的 *
号是正则表达式,*
号表示能够重复前面字符 0 个或多个,因此</*name/*>
能够间接的表示<name>
、</name>
和<name/>
等[[:space:]]
表示匹配空格、制表格等空白符,[[:space:]]*
表示匹配空白字符0个或多个$0
表示取记录的全部记录class
因此,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'