如何使用jq搜索json的值?

时间:2016-04-14 13:47:53

标签: json jq

我有一个这种结构的json:

var v = "str";
/** @var v: Number */
v = 5;

我想用jq查询主机名,mac或IPv6。

{
  "nodes": {
    "60e327ee58a0": {
      "nodeinfo": {
        "network": {
          "mesh": {
            "bat0": {
              "interfaces": {
                "wireless": [
                  "<mac-address-removed>"
                ],
                "tunnel": [
                  "<mac-address-removed>"
                ]
              }
            }
          },
          "mac": "<mac removed>",
          "addresses": [
            "<ipv6 removed>",
            "<ipv6 removed>"
          ]
        },
        "hardware": {
          "model": "TP-Link TL-WR841N/ND v10",
          "nproc": 1
        },
        "software": {
          "batman-adv": {
            "compat": 15,
            "version": "2015.1"
          },
          "autoupdater": {
            "branch": "stable",
            "enabled": true
          },
          "firmware": {
            "release": "v2016.1+1.0.1",
            "base": "gluon-v2016.1"
          },
          "status-page": {
            "api": 1
          },
          "fastd": {
            "enabled": true,
            "version": "v17"
          }
        },
        "hostname": "Antoniusweg12",
        "system": {
          "site_code": "ffmsd03"
        },
        "node_id": "60e327ee58a0"
      },
      "lastseen": "2016-04-14T12:39:04",
      "flags": {
        "gateway": false,
        "online": true
      },
      "firstseen": "2016-03-16T15:14:04",
      "statistics": {
        "clients": 1,
        "gateway": "de:ad:be:ef:43:02",
        "rootfs_usage": 0.6041666666666667,
        "loadavg": 0.09,
        "uptime": 1822037.41,
        "memory_usage": 0.8124737210932025,
        "traffic": {
          "rx": {
            "packets": 50393821,
            "bytes": 5061895206
          },
          "forward": {
            "packets": 173,
            "bytes": 17417
          },
          "mgmt_rx": {
            "packets": 47453745,
            "bytes": 6623785282
          },
          "tx": {
            "packets": 1205695,
            "bytes": 173509528,
            "dropped": 5683
          },
          "mgmt_tx": {
            "packets": 37906725,
            "bytes": 11475209742
          }
        }
      }
    },
    "30b5c2b042f4": {
<next block...>

大多数示例都不适合这种json结构,因为对象具有索引

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

如果您要过滤,则需要深入查看要检查的属性,看它是否符合您的条件。你不能指望给出一个名字,你会神奇地看到你想要的结果。

按主机名搜索,可在每个节点的.nodeinfo.hostname属性中找到:

$ jq -c --arg hostname "Antoniusweg12" \
'.nodes[] | select(.nodeinfo.hostname == $hostname)' nodes.json

类似地,对于mac地址,它位于.nodeinfo.network.mac属性:

$ jq -c --arg mac "aa:bb:cc:dd:ee:ff" \
'.nodes[] | select(.nodeinfo.network.mac == $mac)' nodes.json

对于ip地址,它们有一个数组,但在查询中并没有太大的不同。它们位于.nodeinfo.network.addresses属性:

$ jq -c --arg ip "aaaa:bbbb:cccc:dddd::1" \
'.nodes[] | select(.nodeinfo.network.addresses[] == $ip)' nodes.json

答案 1 :(得分:0)

这是对问题的另一种看法。假设您要查找值为“Antoniusweg12”的所有键“主机名”, 无论键/值组合在何处发生。

以下内容将揭示感兴趣的键/值组合的路径:

POST        /accounts/        @controllers.AccountsController.createOneAccount

给定输入JSON的结果:

paths as $p
| select ( $p[-1] == "hostname" and getpath($p) == "Antoniusweg12" )
| $p

如果您想要包含对象的路径,请将最终[ "nodes", "60e327ee58a0", "nodeinfo", "hostname" ] 替换为$p;如果你想要包含对象本身:$p[0:-1]

答案 2 :(得分:0)

此解决方案可搜索$needleaddressesmac字段中指定hostname所在的节点。

  "<ipv6 removed>" as $needle   # set to whatever you like

| foreach (.nodes|keys[]) as $k (
     .
   ; .
   ;    (      .nodes[$k].nodeinfo.network.addresses?
         + [   .nodes[$k].nodeinfo.network.mac?
             , .nodes[$k].nodeinfo.hostname?
           ]
        ) as $haystack

     | if $haystack | index($needle)
       then {($k): .nodes[$k]}
       else empty
       end
  )

编辑:我现在意识到foreach E as $X (.; .; R)形式的过滤器几乎总是被重写为E as $X | R所以上面的内容实际上就是

  "<ipv6 removed>" as $needle

| (.nodes|keys[]) as $k
| (      .nodes[$k].nodeinfo.network.addresses?
   + [   .nodes[$k].nodeinfo.network.mac?
       , .nodes[$k].nodeinfo.hostname?
     ]
  ) as $haystack

| if $haystack | index($needle)
  then {($k): .nodes[$k]}
  else empty
  end