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"
  }
]

bash スクリプト内で計算される各オブジェクトに、値を持つ名前のキーを追加する必要がありますdays-idle。これが、各 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()呼び出しは、タイムスタンプをドットで切り捨て、その末尾を に置き換えますZ。これは、fromdate解析できるタイムスタンプの種類が少し制限されており、元のタイムスタンプ文字列の 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

これで、 echo を実行してその変数に追加する$objectことができます。jq

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

これに関する重要な注意事項がいくつかあります。オブジェクトが実際にファイル内にある場合、または cURL などの他のストリームから取得されている場合は、echo $object適切なものに置き換えてください。2 番目に、--arg通常作成される文字列ではなく JSON 数値として必要なことを想定しているため、これを修正するためのフィルターがあります。最後に、値を渡す--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
  }
]

関連情報