非標準Jsonを解析する方法は?

非標準Jsonを解析する方法は?

データを取得するために使用しますcurl。出力はJson出力ですが、標準ではありません。試してみましたが、空のjq出力が表示されます。たとえば、

この出力からすべてのIDを抽出して配列に保存したいと思います。

  {"jsonrpc":"3","result":[{"hostid":"16729"},{"hostid":"16736"},{"hostid":"16731"},{"hostid":"16732"},{"hostid":"16733"},{"hostid":"16734"},{"hostid":"16735"},{"hostid":"16736"},{"hostid":"16738"},{"hostid":"16739"},{"hostid":"16746"},{"hostid":"16741"},{"hostid":"16742"},{"hostid":"16743"},{"hostid":"16744"},{"hostid":"16745"},{"hostid":"16746"},{"hostid":"16747"},{"hostid":"16748"},{"hostid":"16749"},{"hostid":"16756"},{"hostid":"16751"},{"hostid":"16752"},{"hostid":"16753"},{"hostid":"16754"},{"hostid":"16755"},{"hostid":"16756"},{"hostid":"16757"},{"hostid":"16758"},{"hostid":"16759"},{"hostid":"16766"},{"hostid":"16761"},{"hostid":"16762"},{"hostid":"16763"},{"hostid":"16764"},{"hostid":"16765"},{"hostid":"16766"},{"hostid":"16767"},{"hostid":"16768"},{"hostid":"16769"},{"hostid":"16776"},{"hostid":"16771"},{"hostid":"16772"},{"hostid":"16773"},{"hostid":"16774"},{"hostid":"16775"},{"hostid":"16776"},{"hostid":"16777"},{"hostid":"16778"},{"hostid":"16779"},{"hostid":"16786"},{"hostid":"16781"},{"hostid":"16782"},{"hostid":"16783"},{"hostid":"16784"},{"hostid":"16785"},{"hostid":"16786"},{"hostid":"16787"},{"hostid":"16788"},{"hostid":"16789"},{"hostid":"16796"},{"hostid":"16791"},{"hostid":"16792"},{"hostid":"16793"},{"hostid":"16794"},{"hostid":"16795"},{"hostid":"16796"},{"hostid":"16797"},{"hostid":"16798"},{"hostid":"16799"},{"hostid":"16866"},{"hostid":"16861"},{"hostid":"16862"},{"hostid":"16863"},{"hostid":"16864"},{"hostid":"16865"},{"hostid":"16866"},{"hostid":"16867"},{"hostid":"16868"},{"hostid":"16869"},{"hostid":"16816"},{"hostid":"16811"},{"hostid":"16812"},{"hostid":"16813"},{"hostid":"16814"},{"hostid":"16815"},{"hostid":"16816"},{"hostid":"16817"},{"hostid":"16818"},{"hostid":"16819"},{"hostid":"16826"},{"hostid":"16821"},{"hostid":"16825"},{"hostid":"16826"},{"hostid":"16827"},{"hostid":"16828"},{"hostid":"16829"},{"hostid":"16836"},{"hostid":"16831"},{"hostid":"11572"},{"hostid":"11573"},{"hostid":"11575"},{"hostid":"11576"},{"hostid":"11586"},{"hostid":"11629"},{"hostid":"11636"},{"hostid":"11632"},{"hostid":"11634"},{"hostid":"11736"},{"hostid":"11737"}],"id":1}  

次のような結果を期待しています。

  ( 16732 16733 ... 11737 )  

Pythonを使用しても正しい結果が得られません。続けてjsonrpcを返します。たとえば、

この出力からIP値を抽出したいです。

  {"jsonrpc":"3","result":[{"interfaceid":"400","hostid":"16796","main":"3","type":"3","useip":"3","ip":"192.168.23.43","dns":"","port":"100","details":[]}],"id":1}

これは長い連結文字列にすぎません。または、他のコマンドを使用して目的のsed効果を得る方法はありますかawk

ベストアンサー1

JSONドキュメントには非標準的な内容はありません。どちらも完全に有効で正しい形式のJSON文書であり、JSON対応ライブラリまたはコマンドラインツールを使用してクエリできます。ここの例ではjqコマンドラインを使用しています。

jqすべての値を配列hostidに保存するには:bash

readarray -t hostid_values < <( jq -r '.result[].hostid' file.json )

これにより、hostidJSONドキュメントの配列からすべての値を抽出して読み込みます。配列内の既存の値はすべて削除されます。resulthostid_valuesbash

同様に、2番目のJSONドキュメントの値をip配列ip_valuesとして読み込みますbash

readarray -t ip_values < <( jq -r '.result[].ip' file.json )

どちらのシェルコードも、値に新しい行またはnullが含まれていないと仮定します。


値に改行文字を挿入したら、次のことを試すことができます。

unset -v hostid_values
eval "$( jq -r '@sh "hostid_values+=( \(.result[].hostid | tonumber) )"' file.json )"

jqこれは配列の割り当てステートメントを作成するために使用されますhostid_values。その後、シェルはこれらのディレクティブを評価します。このtonumber呼び出しは、数値を含む文字列の代わりにコマンド配列を送信し、悪意のある文書がスクリプトにコードを挿入できないようにします(この場合はエラーが発生します)。

ip2番目の文書の値も同じです。

unset -v hostid_values
eval "$( jq -r '@sh "ip_values+=( \(.result[].ip | tostring) )"' file.json )"

おすすめ記事