XMLファイルに設定された値のみを抽出する最も簡単な方法は何ですか?たとえば、XMLファイルのデータは次のとおりです。
<node name="host">
<map>
<entry key="cipher_strength" value="low" />
<entry key="port" value="78234" />
<entry key="over_ssl" value="false" />
<entry key="using_fips" value="true" />
<entry key="ssl_keystore" value="lib/ssl" />
</map>
</node>
low
スクリプトで表示したいです。
これはsed
私が使用するコマンドで、文字列全体を返します。
sed -n '/cipher_strength/{s/.*<cipher_strength>//;s/<\/cipher_strength.*Value=""//;p;}' test.xml
コメントによると、xmlstarlet
私の水洗バージョンでは利用できず、ベンダーがロックされていてインストールできないため、できません。
答え1
コマンドラインXMLパーサーの使用xmlstarlet
:
xmlstarlet sel -t -v '//entry[@key="cipher_strength"]/@value' -nl file.xml
entry
これはXML文書のすべてのノードと一致し、value
同じentry
ノードにkey
値がある属性がある場合はその属性値が抽出されますcipher_strength
。各値は末尾の改行文字とともに出力されます。
xmllint
さまざまなシステムで利用可能な実装は、XPathクエリの実行のサポートが多様であるようです。
私のOpenBSDシステムでは、次のことができます。
xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml
検索する
value="low"
しかし、xmllint --xpath '//entry[@key="cipher_strength"]/@value/text()' file.xml
私はそれが私に文字列を与えることを期待していましたが、うまくいかないようlow
です(ただXPath set is empty
答えを生成するだけです)。
属性値が「nice」の場合、value
この出力を処理して実際の値を抽出できます。
$ xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml | sed -e 's/^[^"]*"//' -e 's/"$//'
low
上記の式は、sed
各行から最初の二重引用符文字まですべてを削除し、最後の二重引用符文字も切り捨てます。
他のxmllint
実装/バージョンでは、次のアプローチを採用している可能性がありますxmllint --shell
。
xmllint --shell file.xml <<<'cat //entry[@key="cipher_strength"]/@value' |
sed -e '/^[^ ]/d' -e 's/^[^"]*"//' -e 's/"$//'
答え2
専用のXMLツールが利用できない場合は、以下を試してくださいawk
。
user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml
スペースで区切られたすべての文字列を含む行を検索し、スペースで区切られたすべてのkey="cipher_strength"
文字列はシンボルから分割されます=
。 「中間」にこのシンボルを含むすべてのシンボルについて(つまり、前に部分があり、後に部分がある)最初の部分が同じであることを確認し、value
そうであれば2番目の部分を印刷します。あなたの意見について
user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml
"low"
ノードが多い場合は、<node>
このタスクを適用する前にプログラムを変更して正しい場所にいることを確認できます。