如何在 jq 中传播对象的属性?

How can I spread an object's properties in jq?

如果我需要访问对象的属性,我目前正在手动访问每个 属性:

echo '{"a": {"a1":1, "a2": 2}, "b": 3}' | jq '{a1:.a.a1, a2: .a.a2,b}'
{
  "a1": 1,
  "a2": 2,
  "b": 3
}

我想避免指定每个 属性。有没有等价于 JS 中的 Object spread operator,比如 jq '{...a, b}'?

您可以将对象添加在一起以合并它们的内容。如果左右对象中都存在键,则右侧对象的值将保留。

echo '{"a": {"a1":1, "a2": 2}, "b": 3}' | jq '.a+{b}'
{
  "a1": 1,
  "a2": 2,
  "b": 3
}

如果您想要一个完全通用的解决方案:

[..|objects|with_entries(select(.value|type!="object"))]|add

或者,如果您想要 depth-first 方法,请将 add 替换为 reverse|add

以上内容当然是基于 add 以有损方式解决冲突的理解。如果你不想要任何损失,选择不同的组合对象的方法,或者根本不组合它们。

这是一个只检查 top-level 值,而不按名称引用任何键的解决方案:

with_entries(if .value|type=="object" then .value|to_entries[] else . end)

例如,这会产生:

{
  "a1": 1,
  "a2": 2,
  "b": 3
}

请注意,即使此解决方案未明确使用 add,它也带有关于键冲突的类似警告。