json - jq - 根据其中一个值查找 JSON 对象并从中获取另一个值

标签 json jq

我最近才开始使用 jq,我想知道这样的事情是否可能。

例子:

{
  "name": "device",
  "version": "1.0.0",
  "address": [
    {
      "address": "10.1.2.3",
      "interface": "wlan1_wifi"
    },
    {
      "address": "10.1.2.5",
      "interface": "wlan2_link"
    },
    {
      "address": "10.1.2.4",
      "interface": "ether1"
    }
  ],
  "wireless": [
    {
      "name": "wlan1_wifi",
      "type": "5Ghz",
      "ssid": "wifi"
    },
    {
      "name": "wlan2_link",
      "type": "2Ghz",
      "ssid": "link"
    }
  ]
}

首先让我们将示例转换为这个 json 对象:
cat json | jq '. | {"name": ."name", "version": ."version", "wireless": [."wireless"[] | {"name": ."name", "type": ."type", "ssid": ."ssid"}]}'
{
  "name": "device",
  "version": "1.0.0",
  "wireless": [
    {
      "name": "wlan1_wifi",
      "type": "5Ghz",
      "ssid": "wifi"
    },
    {
      "name": "wlan2_link",
      "type": "2Ghz",
      "ssid": "link"
    }
  ]
}

现在有一个问题。我需要为 "wireless" 分配一个地址大批。地址存储在"address"大批。

所以问题是:有没有办法在 "address" 中找到正确的 json 对象?基于 "name" (在无线阵列中)和“interface"(在地址阵列中)用于 "wireless" 阵列中的每个 json 对象,然后将 "address" 分配给它?

最终结果应如下所示:
{
  "name": "device",
  "version": "1.0.0",
  "wireless": [
    {
      "name": "wlan1_wifi",
      "type": "5Ghz",
      "ssid": "wifi",
      "address": "10.1.2.3"
    },
    {
      "name": "wlan2_link",
      "type": "2Ghz",
      "ssid": "link",
      "address": "10.1.2.5"
    }
  ]
}

答案:
这是我基于 answer 的回答来自@peak。而不是复制 .wireless 的内容然后使用 map ,我正在挑选我只想包含的键。这也让我可以随意定位“地址”。
(INDEX(.address[]; .interface)) as $dict 
| {name: .name, version: .version, 
wireless: [.wireless[] | {name, address: ($dict[.name]|.address), type, ssid}]}

最佳答案

以下生成最初要求的输出:

(.wireless[].name) as $name
| .address[]
| select(.interface == $name)
| { wireless: {name: $name, address}}

但是,上述过滤器可能会产生多个结果,因此您可能需要进行相应的修改。

订正订正要求

如果你的 jq 有 INDEX/2 (仅在 jq 1.5 发布后才可用),您可以简单地使用它来创建查找表:
(INDEX(.address[]; .interface)) as $dict
| {name,
   version,
   wireless: (.wireless
              | map(. + {address: ($dict[.name]|.address) }) ) }

或者(可能取决于确切的要求):
(INDEX(.address[]; .interface)) as $dict
| del(.address)
| .wireless |= map(. + {address: ($dict[.name]|.address) })

如果您的 jq 没有 INDEX/2 ,那么您可以轻松地调整上述内容(使用 reduce ),或者更轻松地获取 INDEX/2 的定义来自 https://github.com/stedolan/jq/blob/master/src/builtin.jq

关于json - jq - 根据其中一个值查找 JSON 对象并从中获取另一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51558701/

相关文章:

javascript - Backbone.js - 在模型中定义 json 数组

ios - 访问 NSDictionary 数组对象中的第二层数组

java - android如何将json对象转换为json数组

c# - jqgrid 未捕获类型错误 : Cannot read property 'stype' of undefined

json - 输出分号分隔的字符串

json - 使用jq递归提取对象值和父键名

json - 我怎样才能让 jq 按字母顺序漂亮地打印 json 排序键

java - 即使我添加自定义的反序列化器,Jackson 也无法将枚举反序列化为对象

json - JQ -c/--compact-output 无法正常工作? Json解析

json - 通过 jq 删除对象数组中存在的键