You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:22:17