使用 JQ 扩展对 JSON 中同级值的引用

Expand references to sibling values in a JSON using JQ

我有一个 JSON 文档,其中包含宏配置。我需要扩展引用其他元素的宏。为简单起见,请考虑此输入文档。

[
  {
    "first": "Tim",
    "Full": "{first} {last}",
    "last": "Smith"
  },
  {
    "first": "Jane",
    "Full": "{first} {last}",
    "last": "Doe"
  }
]

性能在这里不是最重要的,所以我不介意盲目检查所有其他元素中出现的每个元素。

我制定了以下逻辑作为概念证明。但是无法弄清楚如何在 $lookup 上添加嵌套循环来更新另一个 with_entries 值。

jq  '
  .[]
| . as $lookup
| with_entries(
    .value=(
      .value
      | sub("{first}"; $lookup.first)
    )
  )
'

JQ 处理 values/documents 的流,感觉我现在需要处理两个流。我希望通过使用 $lookup 作为后向参考来实现。现在我卡住了。

解决方案 oguz ismail 为使用 map_values() 的原始问题(请给他们 +1)提供了一个很好的解决方案。很清楚,我想把它放在这里以供参考。您会注意到它在正则表达式中使用了命名组 (?<found_key>.*?)(参见 oniguruma 的 named group

map(. as $lookup | map_values(gsub("\{(?<found_key>.*?)\}"; $lookup[.found_key])))

我问的是结构中有非字符串元素时如何处理。这是一个包含颜色数组的示例:

[
  {
    "first": "Tim",
    "Full": "{first} {last}",
    "last": "Smith",
    "colors": ["red", "blue"]
  }
]

oguz ismail 也为此结构提供了一个解决方案,它只尝试修改字符串元素:

map(
  . as $lookup
  | (.[] | strings)
  |= gsub("\{(?<found_key>.*?)\}"; $lookup[.found_key])
)

您可以将 gsub 与命名捕获组一起使用,以在单个 运行 中扩展所有宏,而无需对它们的名称进行硬编码。而且, with_entries 在这种情况下根本没有帮助;请改用 map_values

map(. as $lookup | map_values(gsub("\{(?<found_key>.*?)\}"; $lookup[.found_key])))

Online demo