【问题标题】:combine array of objects from two files with jq under specific key 1.4在特定键 1.4 下将来自两个文件的对象数组与 jq 组合
【发布时间】:2019-07-22 08:49:10
【问题描述】:

我有两个包含以下 JSON 的文件,我需要使用每个对象的相对数组位置来组合它们:

PS: - 我在 Solaris 上仅限于 1.4 版,所以没有 [inputs] 功能

文件 1

{
  "input": [
    {
      "email": "test1@gm.com",
      "firstName": "Fred"
    },
    {
      "email": "someone@gm.com",
      "firstName": "James"
    }
  ]
}

文件 2:

{
  "result": [
    {
      "id": 50,
      "status": "created"
    },
    {
      "id": 51,
      "status": "rejected"
    }
  ]
}

预期结果是 input[1] 的元素与 result[1] 的元素组合,依此类推:

{
  "combined": [
    {
      "email": "test1@gm.com",
      "firstName": "Fred",
      "id": 50,
      "status": "created"
    },
    {
      "email": "someone@gm.com",
      "firstName": "James",
      "id": 51,
      "status": "rejected"
    }
  ]
}

【问题讨论】:

  • 您好,Paolog,您还记得如果回答对您有帮助,最好将其标记为已接受?

标签: arrays json join merge jq


【解决方案1】:

您可以使用--slurp 选项将两个文件读入一个数组,然后从那里循环遍历其中一个数组的键并将两个数组的相应元素相加是相对简单的。

jq --slurp '
{
  combined: [
    .[0].input as $is|
    .[1].result as $rs|
    range(0; $is|length) as $n|
    $is[$n]+$rs[$n]
  ]
}
' file1.json file2.json

【讨论】:

  • 这种方法很好地避免了reduce,但使用keys 会带来不必要的低效率。最好使用range(0; $is|length) 来实现迭代。
  • @peak 这似乎是正确的(对于“好得多”的值,等于大约 5% 的性能增益和大约 1% 的内存节省在 1M 条目上)。更改代码。
  • @MichałPolitowski - “好得多”我想到了 SO 在说明最佳实践方面所起的作用。
  • @peak,嗯,最佳实践包括衡量变更的影响,不是吗? :)
【解决方案2】:

如果您可以使用更新的 jq 版本,您可以利用 transpose 函数相当轻松地组合它们:

$ jq -n '{ combined: ([inputs[]] | transpose | map(add)) }' input1.json input2.json

但是,由于您仅限于 1.4,因此您的选择有限。处理多个文件时,将所有输入读入内存很有用。 --slurp 允许您将所有输入作为数组读取。但是,您必须以不同的方式将输入压缩在一起。

$ jq --slurp 'add | reduce range(0; .input | length) as $i (.;
    .combined += [.input[$i] + .result[$i]]
) | {combined}' input1.json input2.json

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2021-12-31
    • 2018-08-04
    • 1970-01-01
    相关资源
    最近更新 更多