将 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

现在,我们可以回显$objectthroughjq添加该变量。

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

相关内容