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'
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/156441.html
標籤:Linux

