【问题标题】:JQ How to merge multiple objects into oneJQ 如何将多个对象合并为一个
【发布时间】:2018-12-31 15:28:45
【问题描述】:

给定以下输入(这是输出的低调版本,包含另一个复杂查询的 100K+ 个对象):

echo '{ "a": { "b":"c", "d":"e" } }{ "a": { "b":"f", "d":"g" } }' | jq '.'
{
  "a": {
    "b": "c",
    "d": "e"
  }
}
{
  "a": {
    "b": "f",
    "d": "g"
  }
}

想要的输出:

{
   "c": "e",
   "f": "g"
}

或(更适合后续使用):

{
   x: {
      "c": "e",
      "f": "g"
   }
}

我这辈子都不知道该怎么做。我真正的问题当然是多对象输入数据,我真的不知道它是否是有效的 JSON。 Jq 产生并接受它, jshon 没有。我尝试了各种可能性,但没有一个能产生我需要的东西。我认为这是最有可能的候选人:

echo '{ "a": { "b":"c", "d":"e" } }{ "a": { "b":"f", "d":"g" } }' | jq ' . | { (.a.b): .a.d }'
{
   "c": "e"
}
{
   "f": "g"
}

但是,唉。我尝试过的其他事情:

' . | { x: { (.a.b): .a.d } }'
'{ x: {} | . | add }'
'{ x: {} | . | x += }'
'{ x: {} | x += . }'
'x: {} | .x += { (.a.b): .a.d }'
'{ x: {} } | .x += { (.a.b): .a.d }'

另一个,关闭,但没有信号:

'reduce { (.a.b): .a.d } as $item ({}; . + $item)'
{
  "c": "e"
}
{
  "f": "g"
}

谁愿意开导我?

因此,感谢@peak,上述用例中的完整答案是

echo '{ "a": { "b": "c", "d": "e" } }{ "a": { "b": "f", "d": "g" } }' | jq -n '{ x: [inputs | .a | { (.b): .d} ] | add }'
{
  "x": {
    "c": "e",
    "f": "g"
  }
}

【问题讨论】:

    标签: json object stream jq jsonstream


    【解决方案1】:

    假设您拥有 jq 1.5 或更高版本,并且您的 JSON 对象位于一个或多个文件中。然后对于您的第一个预期输出,您可以简单地编写:

    [inputs | .a | { (.b): .d} ] | add
    

    这假设您使用 -n 命令行选项。我敢肯定,一旦您看到解决方案是多么简单,进一步的解释将是多余的。

    对于您的第二个预期输出,您可以将上面的行包含在:

    {x: _}
    

    例如:

    $ jq -ncf program.jq input.json
    {"x":{"c":"e","f":"g"}}
    

    p.s.您使用 reduce 的方法很好,但您需要使用 -s 命令行选项。

    p.p.s.你还欠我一杯啤酒吗?

    【讨论】:

    • 你已经很接近了,比我现在更接近,我不得不承认,但输入是一个文件:-((PS。要买一个完整的箱子吗?;-) )
    • 正如我所说,无论有多少文件,inputs 的解决方案都可以工作。
    • 不,';'给出一个语法错误(在 linux 上是 am)。留下它给出 { "f": "g" },而不是 { "c": "e", "f": "g" } :-(
    • 该;是一个错字。固定。
    • 省略输入,结果仍然是 | jq'[输入 | .a | { (.b): .d} ] |添加' { "f": "g" } not { "c": "e", "f": "g" }
    猜你喜欢
    • 2019-06-18
    • 2019-06-23
    • 2019-02-07
    • 2018-02-09
    • 2017-04-24
    • 2017-07-23
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多