# 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'