jq - 应用来自文件的修改

jq - apply modifications from a file

我在文件中有一些 json 内容:content.json

{
  "Type": {
    "OS": "Windows"
  },
  "Network": {
     "Protocol": "unknown",
     "Port": 80
  }
}

以及文件中的一些 json 更新:updates.json

{
  "Network": {
    "Protocol": "HTTP"
  }
}

如何使用 jq 读取 updates.json 并将其内容应用到 content.json

警告:我无法预测 updates.json 中的内容。 jq 脚本必须足够聪明,可以应用它找到的任何东西。

输出应该是:

{
  "Type": {
    "OS": "Windows"
  },
  "Network": {
     "Protocol": "HTTP",
     "Port": 80
  }
}

这个脚本几乎我想要的:

jq 'add' -s content.json updates.json

结果是:

{
  "Type": {
    "OS": "Windows"
  },
  "Network": {
    "Protocol": "HTTP"
  }
}

但是如您所见,“端口”条目已被删除。

以下说明了您可以采用的一种方法:

< content.json jq --argfile updates updates.json '
    .Network += $updates.Network
'

或者,根据您的具体要求,您可能会考虑:

< content.json jq --argfile updates updates.json '
  .Network |= with_entries(select(.value != "unknown"))
  | .Network += $updates.Network
'

如果您希望“未知”的出现次数来确定更新:

< content.json jq --argfile updates updates.json '
  reduce paths(. == "unknown") as $p (.;
    setpath($p; $updates | getpath($p)) )
'

也许“递归加法”运算符*能满足您的需求:

< contents.json  jq --argfile updates updates.json '
  . * $updates
'

更通用的方法:

jq -s 'def multiply:reduce .[] as $i ({}; . * $i);
       multiply' content.json updates.json

所以你可以放多个文件。