私は過去数日間stackexchangeを見て達成したいいくつかのことを見つけましたが、それらをどのようにまとめるのかわかりません...
APIのカール呼び出しを作成するスクリプトを作成しようとしています。これにより、特定の値でのみ構文解析したいXMLバンドルが返されます。全体的に、私はこのスクリプトが呼び出しを行い、値を解析して変数に設定してから返す(表示)したいと思います。
ワークソリューションを見つけたかもしれませんが、それは実用的ですか?
#!/bin/bash
test=$(curl -k --silent "https://username:[email protected]?.full=true&name=devicename")
test2=$(curl -k --silent "https://username:[email protected]?.devicestatus&name=devicename")
variable1=$grep -oPm1 "(?<=<name>)[^<]+" <<< "$test:)
variable2=$grep -oPm1 "(?<=<status>)[^<]+" <<< "$test:)
echo "$variable"
echo "$variable2"
[admin]>./script
SwitchName
UP
これは私が採掘したいXMLです。
<?xml version="1.0" ?>
<queryResponse type="AccessPointDetails" rootUrl="https://website/webacs/api/v1/data" requestUrl="https://website/webacs/api/v1/data/AccessPointDetails?.full=true&name=devicename" responseType="listEntityInstances" count="1" first="0" last="0">
<entity url="https://website/webacs/api/v1/data/AccessPointDetails/14008947223" type="AccessPointDetails" dtoType="accessPointDetailsDTO">
<accessPointDetailsDTO id="14008947223" displayName="14008947223">
<clientCount>6</clientCount>
<clientCount_2_4GHz>0</clientCount_2_4GHz>
<clientCount_5GHz>6</clientCount_5GHz>
<ipAddress>172.16.83.5</ipAddress>
<name>devicename</name>
<unifiedApInfo>
......
</unifiedApInfo>
<upTime>609857</upTime>
</accessPointDetailsDTO>
</entity>
</queryResponse>
<?xml version="1.0" ?>
<queryResponse type="AccessPointDetails" rootUrl="https://website/webacs/api/v1/data" requestUrl="https://website/webacs/api/v1/data/AccessPointDetails?.full=true&name=devicename" responseType="listEntityInstances" count="1" first="0" last="0">
<entity url="https://website/webacs/api/v1/data/AccessPointDetails/14008947223" type="AccessPointDetails" dtoType="accessPointDetailsDTO">
<accessPointDetailsDTO id="14008947223" displayName="14008947223">
<name>devicename</name>
<status>UP</status>
<unifiedApInfo>
......
</unifiedApInfo>
</accessPointDetailsDTO>
</entity>
</queryResponse>
ベストアンサー1
まず、あなたの考えを変えるのに役立ついくつかのコメント/質問:
(つまり、コメントから始めて実際の答えに変わったことになります。)
すでに知っている要素を抽出しようとしているのはなぜですか? (URL
devicename
から)XMLを取得するために使用する要素は何ですか?name=devicename
まだなくても、2番目の
curl
コマンド(?.devicestatus
)には要素devicename
とstatus
要素が含まれているので、2番目のコマンドを取得するだけです。あなた
variable1=
とvariable2=
ラインが真剣に混乱しています。両方の行にnotを使用し、$grep
別の二重引用符の代わりに二重引用符を使用して$(grep
二重引用符を終了しました。:
<<< "$test"
つまり、代わりにこのように見えるはずです<<< "$test:
他の人がすでにコメントで述べたように、正規表現を使用してXMLを解析することは実際には良いアプローチではありません。
xmlstarlet
たとえば、シェルスクリプトでXMLを処理するのに役立つツールであるXMLプロセッサを代わりに使用します。または、言語(たとえばperl
、python
利用可能なXML処理ライブラリを含む言語)でスクリプトを作成します。このサイトを検索してhttps://stackoverflow.com/多くの例)。上記の3.と4.のため、あなたの質問に対する答えは「いいえ、まったく機能せず、ここで正規表現を使用してはいけないので実用的ではありません」です。
今、いくつかの可能な解決策は次のとおりです。
これにより、スクリプトの構文エラーを修正して実行することができます。
#!/bin/bash
test=$(curl -k --silent "https://username:[email protected]?.full=true&name=devicename")
test2=$(curl -k --silent "https://username:[email protected]?.devicestatus&name=devicename")
variable1=$(grep -oPm1 "(?<=<name>)[^<]+" <<< "$test1")
variable2=$(grep -oPm1 "(?<=<status>)[^<]+" <<< "$test2")
echo "$variable"
echo "$variable2"
しかし、これは特に正規表現がXMLを安定して解析できないため、最適とは離れています。これを試すことは、せいぜい醜いハッキングであり、条件(XML入力など)が抽出したいものに完全に完全である場合にのみ機能します。サーバーからXML出力を少し変更しても(改行を含む余分なスペースを削除するなど)、スクリプトが破損する可能性があります。
私があなたがやっていることをやろうとしたら、おおよそ次のようにします。
#!/bin/bash
U='username'
P='password'
site='website.api.address'
element_base='queryResponse/entity'
element_AP="${element_base}/accessPointDetailsDTO"
element_status="${element_AP}/status"
devname='devicename'
url="https://${U}:${P}@${site}?.devicestatus&name=${devname}"
xml=$(curl -k --silent "$url")
status=$(printf '%s\n' "$xml" | xmlstarlet sel -t -v "$element_status")
echo "$devname: $status"
このようにスクリプトを作成する際に役立つ1つは、さまざまな変数からさまざまな文字列($url
特に$element_status
)を作成することで、誤字やその他のエラーの危険なしに簡単に変更できることです。コマンドライン(たとえば、コマンドラインオプションの処理などU="$1" ; P="$2" ; devname="$3"
)、設定ファイル、またはその両方からインポートすることもできます。コマンドラインに複数を提供してループにインポートすることもできます。getopts
-u username -p passsword -d devicename
devname
以下は、これらのアイデアのいくつかを組み合わせた別のバージョンのスクリプトです。
#!/bin/bash
# get username and password, and remove them from the args
U="$1" ; shift
P="$1" ; shift #edited. was $2
site='website.api.address'
element_base='queryResponse/entity'
element_AP="${element_base}/accessPointDetailsDTO"
element_status="${element_AP}/status"
url="https://${U}:${P}@${site}?.devicestatus"
for devname in "$@" ; do
xml=$(curl -k --silent "${url}&name=${devname}")
status=$(printf '%s\n' "$xml" | xmlstarlet sel -t -v "$element_status")
echo "$devname: $status"
done