何が間違っているのかを理解するのに役立ちます。
"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>[email protected]</rowDescription>
</record>
</step>
</transaction>
</sequence>
PostDateを抽出して変数に入れようとしています。私のスクリプト:
#!/bin/ksh
dbDATE=$(sed -n -e "s/<postingDate>\([0-9]*\)<\/postingDate>/\1/p" res.xml)
echo "current DB date: $dbDATE"
実行すると、何も出ず、空白だけが表示されます。
他の場所でも同じロジックを問題なく使用したので、これは奇妙です。見逃した部分を誰でも見ることができますか? ? ?
あなたが提供できるどんな助けにも心から感謝します。
答え1
アプローチの主な問題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 )
答え2
.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>[email protected]</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}')
答え3
次のコマンドを使用するとうまく動作します
dbdate=$(awk -F "[<>]" '/postingDate/{print $3}' res.xml)
echo -e "current DB date: $dbdate"
current DB date: 2021-08-02