如何用JQ扁平化多维JSON并过滤出开放端口的条目?
处理JSON数据:扁平化端口条目并过滤开放端口
我有如下JSON文件test.json:
[ { "status": { "+@state": "up" }, "address": { "+@addr": "10.10.10.1", "+@addrtype": "ipv4" }, "ports": { "port": [ { "+@protocol": "tcp", "+@portid": "80", "state": { "+@state": "open" } }, { "+@protocol": "tcp", "+@portid": "443", "state": { "+@state": "closed" } } ] } }, { "status": { "+@state": "down" }, "address": { "+@addr": "10.10.10.2", "+@addrtype": "ipv4" }, "ports": { "port": [ { "+@protocol": "tcp", "+@portid": "21", "state": { "+@state": "closed" } }, { "+@protocol": "tcp", "+@portid": "22", "state": { "+@state": "closed" } } ] } }, { "status": { "+@state": "up" }, "address": { "+@addr": "10.10.10.3", "+@addrtype": "ipv4" }, "ports": { "port": [ { "+@protocol": "tcp", "+@portid": "21", "state": { "+@state": "closed" } }, { "+@protocol": "tcp", "+@portid": "22", "state": { "+@state": "closed" } } ] } }, { "status": { "+@state": "up" }, "address": { "+@addr": "10.10.10.4", "+@addrtype": "ipv4" }, "ports": { "port": [ { "+@protocol": "tcp", "+@portid": "21", "state": { "+@state": "open" } }, { "+@protocol": "tcp", "+@portid": "22", "state": { "+@state": "open" } } ] } } ]
之前执行的命令输出存在重复条目,且未过滤关闭的端口。要实现每个开放端口对应一个包含主机地址的对象,可以使用以下jq命令:
jq '[ .[] | select(.status."+@state" == "up") | .address as $addr | .ports.port[] | select(.state."+@state" == "open") | { address: $addr."+@addr", port: ."+@portid" } ]' test.json
命令分步解释:
.[]:遍历原始数组中的每台主机对象select(.status."+@state" == "up"):只保留状态为up的主机.address as $addr:将当前主机的地址对象存入变量$addr,后续处理端口时可以直接引用.ports.port[]:展开主机的端口数组,把每个端口单独作为处理对象select(.state."+@state" == "open"):筛选出状态为open的端口{ address: $addr."+@addr", port: ."+@portid" }:构造目标格式的对象,从变量中提取主机地址,从当前端口对象提取端口号
执行命令后得到的期望输出:
[ { "address": "10.10.10.1", "port": "80" }, { "address": "10.10.10.4", "port": "21" }, { "address": "10.10.10.4", "port": "22" } ]
内容的提问来源于stack exchange,提问作者user1822391
相关产品推荐
相关产品推荐

