Sed

在 KSH 中查找文件元素

  • August 7, 2021

請幫我弄清楚我做錯了什麼。

我有一個名為“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}')

引用自:https://unix.stackexchange.com/questions/663612