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'


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM