Bash変数をJSONキーと値としてオブジェクトに追加する

Bash変数をJSONキーと値としてオブジェクトに追加する

このようなJSONオブジェクトの配列があります。

[
  {
    "id" : "tmp1387816934708382026",
    "owner" : "john",
    "x11-display" : ":5",
    "x11-authority" : "/run/user/john/dcv/tmp1387816934708382026.xauth",
    "num-of-connections" : 1,
    "creation-time" : "2019-05-14T14:12:14.989287Z",
    "last-disconnection-time" : "2019-05-31T18:58:42.851223Z"
  },
  {
    "id" : "tmp4241942441012516520",
    "owner" : "mike",
    "x11-display" : ":10",
    "x11-authority" : "/run/user/mike/dcv/tmp4241942441012516520.xauth",
    "num-of-connections" : 0,
    "creation-time" : "2019-05-17T16:23:05.891531Z",
    "last-disconnection-time" : "2019-05-19T11:23:30.844797Z"
  }
]

days-idleBashスクリプトで計算されたすべてのオブジェクトに値名のキーを追加する必要があります。これが私がすべてのJSONオブジェクトで探しているものです。

{
    "id" : "tmp1387816934708382026",
    "owner" : "mike",
    "x11-display" : ":5",
    "x11-authority" : "/run/user/mike/dcv/tmp1387816934708382026.xauth",
    "num-of-connections" : 1,
    "creation-time" : "2019-05-14T14:12:14.989287Z",
    "last-disconnection-time" : "2019-05-31T18:58:42.851223Z",
    "days-idle" : "$daysIdle"
  }

キーを追加できることを知っていますが、jq値がbash変数であるキーと値のペアを追加する方法がわかりません。

答え1

特定の値を持つ要素に新しいキーを追加するとします.id$id

jq --arg id "$id" --arg idle "$daysIdle" \
    '( .[] | select(.id == $id)."days-idle" ) |= $idle' file

.idこれは変更したい配列要素を選択して追加します(実際には修正する."days-idle"私たちが望む特定の値を持つ要素のキー。

."days-idle"タイムスタンプとタイムスタンプの間の時間でなければならない場合."last-disconnection-time"、次のようにJSONのすべての要素を更新できます。

jq 'def dayssince: ((now - (sub("[.].*"; "Z") | fromdate))/86400) | round;
    map(. += { "days-idle": (."last-disconnection-time" | dayssince) })' file

このsub()呼び出しは、そのポイントのタイムスタンプを切り捨て、末尾をZfromdateこれは、解析できるタイムスタンプの種類が多少制限されており、生のタイムスタンプ文字列の1秒未満の精度を処理しないためです。

私はコードをきれいに保つためにjqタイムスタンプの後の日数を実際に計算することにしました。dayssince

生成されたJSON(2021年6月28日ランタイム):

[
  {
    "id": "tmp1387816934708382026",
    "owner": "john",
    "x11-display": ":5",
    "x11-authority": "/run/user/john/dcv/tmp1387816934708382026.xauth",
    "num-of-connections": 1,
    "creation-time": "2019-05-14T14:12:14.989287Z",
    "last-disconnection-time": "2019-05-31T18:58:42.851223Z",
    "days-idle": 759
  },
  {
    "id": "tmp4241942441012516520",
    "owner": "mike",
    "x11-display": ":10",
    "x11-authority": "/run/user/mike/dcv/tmp4241942441012516520.xauth",
    "num-of-connections": 0,
    "creation-time": "2019-05-17T16:23:05.891531Z",
    "last-disconnection-time": "2019-05-19T11:23:30.844797Z",
    "days-idle": 771
  }
]

答え2

まず、Bash変数にJSONオブジェクトの配列があるとしましょう。

bash$ object='[
  {
    "id" : "tmp1387816934708382026",
    "owner" : "john",
    "x11-display" : ":5",
    "x11-authority" : "/run/user/john/dcv/tmp1387816934708382026.xauth",
    "num-of-connections" : 1,
    "creation-time" : "2019-05-14T14:12:14.989287Z",
    "last-disconnection-time" : "2019-05-31T18:58:42.851223Z"
  },
  {
    "id" : "tmp4241942441012516520",
    "owner" : "mike",
    "x11-display" : ":10",
    "x11-authority" : "/run/user/mike/dcv/tmp4241942441012516520.xauth",
    "num-of-connections" : 0,
    "creation-time" : "2019-05-17T16:23:05.891531Z",
    "last-disconnection-time" : "2019-05-19T11:23:30.844797Z"
  }
]'

$daysIdle次に、変更可能で数字を含むと仮定します。

bash$ daysIdle=3

これで、その変数を追加してエコーでき$objectますjq

bash$ echo "$object" | jq --arg daysIdle "$daysIdle" '.[]."days-idle" = ($daysIdle | tonumber)'

これに関するいくつかの重要な注意事項です。オブジェクトが実際にファイルにある場合、または別のストリーム(cURLなど)から来る場合は、echo $object適切なコンテンツを置き換えることができます。第二に、通常は生成された文字列ではなくJSON番号が欲しいと仮定するので、--argそれを修正するためのフィルタがあります。最後に、--argオプションを使用して値を渡すことに注意してくださいjq。これは、JSONフィルタ文字列自体に値を挿入するよりもはるかに優れており、安全であり、構文エラーは発生しません。数値に変換できないとエラーが発生しますが、フィルタ文字列のランダム注入は許可されません。それでは、出力を見てみましょう。

[
  {
    "id": "tmp1387816934708382026",
    "owner": "john",
    "x11-display": ":5",
    "x11-authority": "/run/user/john/dcv/tmp1387816934708382026.xauth",
    "num-of-connections": 1,
    "creation-time": "2019-05-14T14:12:14.989287Z",
    "last-disconnection-time": "2019-05-31T18:58:42.851223Z",
    "days-idle": 3
  },
  {
    "id": "tmp4241942441012516520",
    "owner": "mike",
    "x11-display": ":10",
    "x11-authority": "/run/user/mike/dcv/tmp4241942441012516520.xauth",
    "num-of-connections": 0,
    "creation-time": "2019-05-17T16:23:05.891531Z",
    "last-disconnection-time": "2019-05-19T11:23:30.844797Z",
    "days-idle": 3
  }
]

関連情報