Sed
在 KSH 中查找文件元素
請幫我弄清楚我做錯了什麼。
我有一個名為“res.xml”的文件
<sequence type="a"> <transaction> <branchSerial>1</branchSerial> <postingDate>2021-08-02</postingDate> <postingTime>2021-08-06 19:42:49 UTC</postingTime> <step type="a"> <record type="c" label="deviceRecord"> <operation option="V">View</operation> <tableName>DEVICE</tableName> <tableDescription>Device</tableDescription> <rowDescription>person@chello.com</rowDescription> </record> </step> </transaction> </sequence>
我正在嘗試拉出postingDate 並放入一個變數中。我的腳本:
#!/bin/ksh dbDATE=$(sed -n -e "s/<postingDate>\([0-9]*\)<\/postingDate>/\1/p" res.xml) echo "current DB date: $dbDATE"
當我執行它時,我什麼也沒得到,只是空白。
這很奇怪,因為我在其他地方使用了相同的邏輯而沒有問題。誰能看到我錯過了什麼???
非常感謝您提供的任何幫助
您的方法的主要問題
sed
是您不允許日期包含破折號。要從您顯示的文件中提取數據,您可以在命令行中使用支持 XML 的解析器。
這種解析器的一個範例是
xmlstarlet
,您可以像這樣使用它:dbDATE=$( xmlstarlet sel -t -v '/sequence/transaction/postingDate' res.xml )
或者,如果您要查找 的值的節點是唯一的此類節點,
dbDATE=$( xmlstarlet sel -t -v '//postingDate' res.xml )
另一個支持 XML 的解析器是
xq
一個圍繞 JSON 解析器的 XML 解析器包裝器jq
:dbDATE=$( xq -r '.sequence.transaction.postingDate' res.xml )
以上所有假設
sequence
節點只包含一個transaction
節點。我們是否要支持多個交易(“序列”一詞暗示這可能包含交易列表),您還需要決定是否要選擇第一個交易或給定其他條件的特定交易。假設我們想要一個
branchSerial
價值為的交易1
。與xmlstarlet
:dbDATE=$( xmlstarlet sel -t -v '/sequence/transaction[branchSerial=1]/postingDate' res.xml )
與
xq
:dbDATE=$( xq -r '.sequence.transaction[] | select(.branchSerial == "1").postingDate' res.xml )
假設您將 .xml 輸出設置為變數,您可以執行以下操作:
xmlData=' <sequence type="a"> <transaction> <branchSerial>1</branchSerial> <postingDate>2021-08-02</postingDate> <postingTime>2021-08-06 19:42:49 UTC</postingTime> <step type="a"> <record type="c" label="deviceRecord"> <operation option="V">View</operation> <tableName>DEVICE</tableName> <tableDescription>Device</tableDescription> <rowDescription>person@chello.com</rowDescription> </record> </step> </transaction> </sequence> ' date=$(echo "$xmlData" | grep "postingDate" | tr '>' " " | tr '<' " " | awk '{print $2}')
既然你說你是從文件中提取它,你甚至可以這樣做:
date=$(cat res.xml | grep "postingDate" | tr '>' " " | tr '<' " " | awk '{print $2}')