JQ-根据其中一个值查找JSON对象并从中获取另一个值 [英] jq - Find a JSON object based on one of its values and get another value from it

查看:14
本文介绍了JQ-根据其中一个值查找JSON对象并从中获取另一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近才开始使用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"数组中。

所以问题是:有没有办法根据"name"(在无线阵列中)和interface"(在地址数组中)为"wireless"数组中的每个json对象找到正确的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"
    }
  ]
}

答案: 以下是我基于@Peak的answer的答案。我没有复制.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),或者更容易从https://github.com/stedolan/jq/blob/master/src/builtin.jq

中snarfINDEX/2

这篇关于JQ-根据其中一个值查找JSON对象并从中获取另一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆