77

我想转换对象流:

{
  "a": "green",
  "b": "white"
}
{
  "a": "red",
  "c": "purple"
}

成一个对象:

{
  "a": "red",
  "b": "white",
  "c": "purple"
}

另外,如何将相同的序列包装到数组中?

[
    {
      "a": "green",
      "b": "white"
    },
    {
      "a": "red",
      "c": "purple"
    }
]

可悲的是,该手册严重缺乏全面性,谷歌搜索也找不到答案。

4

4 回答 4

113

如果您的输入是对象流,那么除非您的 jq 具有inputs,否则必须“slurped”对象,例如使用 -s 命令行选项,以便将它们组合起来。

因此,在输入流中组合对象的一种方法是使用:

jq -s add

对于第二个问题,创建一个数组:

jq -s .

当然还有其他选择,但这些都很简单,不需要最新版本的 jq。使用 jq 1.5 及更高版本,您可以使用“输入”,例如jq -n '[inputs]'

高效的解决方案

对于第一个问题(减少),而不是 slurping(无论是通过 -s 选项还是使用),使用with和 -n 命令行选项[inputs]会更有效。例如,要将对象流组合成一个对象:reduceinputs

jq -n 'reduce inputs as $in (null; . + $in)'

等效地,没有--null-input

jq 'reduce inputs as $in (.; . + $in)
于 2015-12-27T04:56:04.123 回答
32

使用 -s 命令行选项 slurping 的替代方法是使用inputs过滤器。像这样:

jq -n '[inputs] | add'

这将生成一个包含所有输入对象的对象。

于 2017-12-22T23:30:38.637 回答
6

如果您通过 jq 过滤器而不是外部输入达到这一点,mwag 的评论建议将您的 jq 过滤器包装在[]s 中可能会有用。

例子:

$ echo '[{"foo":42},{"foo":43}]' | jq '.[]'
{
  "foo": 42
}
{
  "foo": 43
}
$ echo '[{"foo":42},{"foo":43}]' | jq '[.[]]'
[
  {
    "foo": 42
  },
  {
    "foo": 43
  }
]

另请参阅jq Github 问题 #684:从对象创建数组?.

于 2021-01-21T17:47:09.723 回答
5

要将对象组合成一个数组,您可以使用以下命令:

$ echo '
{
  "a": "green",
  "b": "white"
}
{
  "a": "red",
  "c": "purple"
}' | jq -n '[inputs]'
[
  {
    "a": "green",
    "b": "white"
  },
  {
    "a": "red",
    "c": "purple"
  }
]
于 2020-07-30T13:33:48.450 回答