2016-04-14 1 views
0

У меня есть JSON этой структуры:Как искать json с jq для значений?

{ 
    "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...> 

И я хочу, чтобы запросить его с JQ для имени хоста, макинтош или IPv6.

cat nodes.json |jq -c '.nodes[] | select(.nodes[]| contains("Antoniusweg12"))' 

Большинство примеров не подходят такого рода структуры JSon как объекты имеют индекс

Спасибо за помощь заранее.

ответ

0

Если вы собираетесь фильтровать, вам необходимо перейти к собственности, которую вы хотите проверить, и посмотреть, соответствует ли она вашим критериям. Вы не можете рассчитывать просто дать имя, и вам будут представлены магические результаты, которые вы хотите.

Поиск по имени хоста, она находится на .nodeinfo.hostname свойство каждого узла:

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

Аналогично адрес макинтоша, он находится на .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 
0

Вот еще принять по этому вопросу. Предположим, вы хотите найти все вхождения ключа «имя хоста», для которого значение «Antoniusweg12», независимо от того, где происходит комбинация клавиш/значений.

Следующая покажет путь к комбинации клавиш/значение интереса:

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

Результат для данного входного JSON:

[ 
    "nodes", 
    "60e327ee58a0", 
    "nodeinfo", 
    "hostname" 
] 

Если вы хотите путь к содержащей объект , затем замените окончательный $p на $p[0:-1]; и если вы хотите сам объект, содержащий: getpath($p[0:-1])

0

Вот решение, которое ищет узлы, где указанный $needle присутствует в любом из addresses, mac или 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 
) 

EDIT: Теперь я понимаю, фильтр формы 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 
Смежные вопросы