Json 使用jq将对象数组转换为数组对象

Json 使用jq将对象数组转换为数组对象,json,jq,Json,Jq,我想使用jq将对象数组转换为数组对象 考虑我是否有以下两个文件: file1.json: { "key1": 5, "key2": 10 } { "key1": 2 } file2.json: { "key1": 5, "key2": 10 } { "key1": 2 } 我想将它们合并在一起,形成: { "key1": [5, 2] "key2": [10, null] } 每个jq命令使用一个字段很容易做到这一点,但我不知道如何同时使用所有字段。我的

我想使用
jq
将对象数组转换为数组对象

考虑我是否有以下两个文件:

file1.json

{
  "key1": 5,
  "key2": 10
}
{
  "key1": 2
}
file2.json

{
  "key1": 5,
  "key2": 10
}
{
  "key1": 2
}
我想将它们合并在一起,形成:

{
  "key1": [5, 2]
  "key2": [10, null]
}
每个
jq
命令使用一个字段很容易做到这一点,但我不知道如何同时使用所有字段。我的想法是,我需要将所有值转换为数组,然后使用reduce和
*
,但我无法让它工作


jq
命令需要用于任意数量的文件(超过2个)。

以下内容将按照您的描述将一个对象数组合并为一个对象(特别是,null用作填充符,例如,如果每个输入对象都被视为“观察值”,这当然是有意义的),但是请注意,此处定义的merge/0没有对输入对象中的键集进行任何假设,并且可能会更快,这取决于所做的假设

def merge:
  def allkeys: map(keys) | add | unique;
  allkeys as $allkeys
  | reduce .[] as $in ({};
     reduce $allkeys[] as $k (.;
       . + {($k): (.[$k] + [$in[$k]]) } ));

merge
现在使用“slurp”选项,例如:

 $ jq -s -f merge.jq file*.json

这可能比@peak的解决方案慢,但可能更容易阅读:

map(to_entries)
| flatten(1)
| group_by(.key)
| map({
    key: .[0].key,
    value: map(.value)})
| from_entries
像这样使用它:

jq -s 'map(to_entries) | flatten(1) | group_by(.key) | map({key: .[0].key, value: map(.value)}) | from_entries' file*.json

与所需的输出不同,它不会将空值替换缺少的值,如果“null”本身是有效值,这可能会很有用。

这里是另一种解决方案

  (add | keys) as $all                                                  # get all keys
| map( . as $o | reduce $all[] as $k ({}; .[$k] = $o[$k]) )             # normalize objects
|    ( . as $a | reduce $all[] as $k ({}; .[$k] = ($a | map(.[$k]))) )  # transpose
要运行它,请使用
-s
选项,例如:

$ jq -s -f filter.jq file1.json file2.json
样本输出:

{
  "key1": [
    5,
    2
  ],
  "key2": [
    10,
    null
  ]
}
{
  "key1": [
    5,
    2,
    null
  ],
  "key2": [
    10,
    null,
    null
  ],
  "key3": [
    null,
    null,
    2
  ]
}
如果您有更多文件,例如
file3.json

{
  "key3": 2
}
只需将它们添加到命令行

$ jq -s -f filter.jq file1.json file2.json file3.json
样本输出:

{
  "key1": [
    5,
    2
  ],
  "key2": [
    10,
    null
  ]
}
{
  "key1": [
    5,
    2,
    null
  ],
  "key2": [
    10,
    null,
    null
  ],
  "key3": [
    null,
    null,
    2
  ]
}

您如何让它处理任意数量的文件?@schmmd——请注意,merge/0的原始版本不够通用。