將 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-idle向 bash 腳本中計算的每個物件添加一個以值命名的鍵。這就是我在每個 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它可以解析的時間戳類型有點限制,並且不處理原始時間戳字串的亞秒精度。

我決定將自時間戳以來的天數的實際計算作為一個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

現在,我們可以回顯$objectthrough來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
  }
]

相關內容