如何筛选OPNSense防火墙VLAN配置中selected=1的子属性?
用jq精简OPNSense VLAN配置JSON
假设你的原始JSON结构类似这样:
{ "vlans": [ { "if": "em0", "pcp": [ {"value": 0, "selected": 0}, {"value": 3, "selected": 1} ], "proto": [ {"value": "802.1Q", "selected": 1}, {"value": "802.1ad", "selected": 0} ], "description": "要移除的字段" }, { "if": "em1", "pcp": [{"value": 5, "selected": 1}], "proto": [{"value": "802.1ad", "selected": 0}], "other": "无用字段" } ] }
要保留if字段,以及pcp、proto数组中selected等于1的子元素,用以下jq命令:
jq '.vlans |= map({ if: .if, pcp: (.pcp | map(select(.selected == 1))), proto: (.proto | map(select(.selected == 1))) })' input.json > output.json
执行后得到的精简结果:
{ "vlans": [ { "if": "em0", "pcp": [{"value": 3, "selected": 1}], "proto": [{"value": "802.1Q", "selected": 1}] }, { "if": "em1", "pcp": [{"value": 5, "selected": 1}], "proto": [] } ] }
如果希望过滤后子数组为空时自动移除该字段,用进阶版命令:
jq '.vlans |= map( .if as $if | (.pcp | map(select(.selected == 1))) as $pcp | (.proto | map(select(.selected == 1))) as $proto | {} | .if = $if | if $pcp != [] then .pcp = $pcp else . end | if $proto != [] then .proto = $proto else . end )' input.json > output.json
此时第二个VLAN的proto字段会被移除,结果如下:
{ "vlans": [ { "if": "em0", "pcp": [{"value": 3, "selected": 1}], "proto": [{"value": "802.1Q", "selected": 1}] }, { "if": "em1", "pcp": [{"value": 5, "selected": 1}] } ] }
核心逻辑说明:
map(...)遍历每个VLAN对象,生成新的对象结构select(.selected == 1)筛选子属性中符合条件的元素map(select(...))对数组整体过滤,保留符合条件的元素- 进阶版通过变量缓存过滤结果,再根据是否为空决定是否保留字段
内容的提问来源于stack exchange,提问作者NorbertK
相关产品推荐
相关产品推荐

