Json 将数组映射到没有公共字段的对象

Json 将数组映射到没有公共字段的对象,json,bash,merge,jq,Json,Bash,Merge,Jq,假设所有元素的顺序都是可预测的,那么如何使用jq-1.5-1-a5b5cbe将STDIN中经过过滤的数组集连接到不包含公共字段的对象集呢 标准输入前文件;由多个get生成: {"ref":"objA","arr":["alpha"]} {"ref":"objB","arr":["bravo"]} 现有文件: [{"name":"foo"},{"name":"bar"}] 期望输出: [{"name":"foo","arr":["alpha"]},{"name":"bar","arr":["b

假设所有元素的顺序都是可预测的,那么如何使用jq-1.5-1-a5b5cbe将STDIN中经过过滤的数组集连接到不包含公共字段的对象集呢

标准输入前文件;由多个get生成:

{"ref":"objA","arr":["alpha"]}
{"ref":"objB","arr":["bravo"]}
现有文件:

[{"name":"foo"},{"name":"bar"}]
期望输出:

[{"name":"foo","arr":["alpha"]},{"name":"bar","arr":["bravo"]}]
当前Bash:

$ multiGET | jq --slurpfile stdin /dev/stdin '.[].arr = $stdin[].arr' file
[
  {
    "name": "foo",
    "arr": [
      "alpha"
    ]
  },
  {
    "name": "bar",
    "arr": [
      "alpha"
    ]
  }
]
[
  {
    "name": "foo",
    "arr": [
      "bravo"
    ]
  },
  {
    "name": "bar",
    "arr": [
      "bravo"
    ]
  }
]
旁注:我不确定在这个问题中何时使用pretty/compact JSON;请就最佳实践发表意见

无论是使用-s还是-slurpfile,Slurping有时是必要的,但由于内存需求,很少有必要。因此,这里有一个解决方案,它利用了multiGET生成流这一事实: 如果您的流实际上已经打包为数组,那么以下是一种功能性方法: 如果$objects数组位于文件中或对于命令行来说太大,我建议使用-argfile,尽管从技术上讲它是不推荐的

如果$objects数组在一个文件中,并且如果您想要避免-argfile,您仍然可以避免slurping,例如,通过使用以下事实,除非使用-n,否则jq将自动从stdin读取一个JSON实体:

让jq在stdin之前读取文件,这样文件中的第一个实体将被删除。您可以使用输入获取其他所有内容


看起来最后一个和我的相似,但更好。我想你应该证明它也可以像multiGET | jq一样使用。。。文件-我可以删除我的答案我建议保留你的答案。它展示了如何使用reduce,以及它的优缺点。好吧。看起来+=也是使用reduce/foreach实现的,在reduce中处理一个大对象确实会减慢程序的速度。我选择了oguz的修改答案,因为它是在复杂的shell脚本中实现的最简单的方法,但我要感谢您花时间编写和解释多种方法。你的答案是一个很好的练习,它提高了我对语言的整体理解。我喜欢这个解决方案,因为它不需要删除不相关的键。我之所以选择你的答案,是因为这个评论;请编辑,使它成为任何人在这个问题上绊倒的第一件事阅读。非常感谢。
multiGET | jq -n --argjson objects '[{"name":"foo"},{"name":"bar"}]' '
  $objects
  | [foreach inputs as $in (-1; .+1; 
      . as $ix
      | $objects[$ix] + ($in | del(.ref)))]
'
multiGET | jq -s --argjson objects '[{"name":"foo"},{"name":"bar"}]' '
  [$objects, map(del(.ref))]
  | transpose
  | map(add)
'
(echo '[{"name":"foo"},{"name":"bar"}]';
 multiGET) | jq '
   . as $objects
   | [foreach inputs as $in (-1; .+1;
        . as $ix | $objects[$ix] + $in | del(.ref))] 
'
$ multiGET | jq -c '. as $objects
| [ foreach (inputs | {arr}) as $x (-1; .+1;
    . as $i | $objects[$i] + $x
) ]' file -
[{"name":"foo","arr":["alpha"]},{"name":"bar","arr":["bravo"]}]