jq: Select 使用 2x 独立级密钥
jq: Select using 2x seperate-level keys
在 JSON 数据上使用 jq ...
我正在尝试 select 在同一记录元素中记录 FromPort 为 80 且 CidrIp 为 0.0.0.0/0 的记录。
这里是查询:
cat data.json |jq -r '.SecurityGroups | .[] | select((.IpPermissions[] | .IpRanges[] | .CidrIp == "0.0.0.0/0") and (.IpPermissions[] | .FromPort == 80))'
数据如下
结果应该只有 select Group3,而不是 selects Group1 和 Group3。我尝试了各种 google 搜索,但仍无法找到答案。
非常感谢任何帮助。
数据(data.json):
{
"SecurityGroups": [
{
"GroupName": "Group1",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
}
]
},
{
"GroupName": "Group2",
"IpPermissions": [
{
"FromPort": 443,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6788,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
},
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
]
}
您选择的迭代 .IpPermissions[] | .IpRanges[]
产生的结果与这些数组中的项目一样多。对于每个 true
结果,您的 select
传递有问题的输入(可能多次)。您需要像 any
或 all
这样的聚合器将所有结果组合成一个布尔结果,这样 select
就可以传递相应输入的 1 个或 0 个副本。
此外,您在 and
的 两边 迭代 .IpPermissions[]
在您的条件下,这将产生结果的笛卡尔积。
如果 .IpPermissions
数组中有 至少一个 项目与 .FromPort
并且至少有一个 与 .IpRanges
数组中的 .CidrIp
匹配:
jq '
.SecurityGroups[] | select(
any(.IpPermissions[]; .FromPort == 80 and
any(.IpRanges[]; .CidrIp == "0.0.0.0/0")
)
)
' data.json
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
你可以适当的使用括号()
和and
来过滤,像这样:(.FromPort==80 and (.IpRanges[] | .CidrIp=="0.0.0.0/0" ))
。通过这样做,我们确保两个条件都与IpPermissions
.
中的条目匹配
过滤器
.SecurityGroups | map(select(.IpPermissions[]
| (.FromPort==80 and (.IpRanges[] | .CidrIp=="0.0.0.0/0" ))))
输入
{
"SecurityGroups": [
{
"GroupName": "Group1",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
}
]
},
{
"GroupName": "Group2",
"IpPermissions": [
{
"FromPort": 443,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6788,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
},
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
]
}
输出
[
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
]
现在只能看到输出了Group3
演示
https://jqplay.org/s/qZvARp_5LE
或者您可以按照 pmf 的建议使用 any/2
。
过滤器
.SecurityGroups[]
| select(any(.IpPermissions[]; .FromPort==80
and any(.IpRanges[]; .CidrIp=="0.0.0.0/0")))
演示
在 JSON 数据上使用 jq ...
我正在尝试 select 在同一记录元素中记录 FromPort 为 80 且 CidrIp 为 0.0.0.0/0 的记录。
这里是查询:
cat data.json |jq -r '.SecurityGroups | .[] | select((.IpPermissions[] | .IpRanges[] | .CidrIp == "0.0.0.0/0") and (.IpPermissions[] | .FromPort == 80))'
数据如下
结果应该只有 select Group3,而不是 selects Group1 和 Group3。我尝试了各种 google 搜索,但仍无法找到答案。
非常感谢任何帮助。
数据(data.json):
{
"SecurityGroups": [
{
"GroupName": "Group1",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
}
]
},
{
"GroupName": "Group2",
"IpPermissions": [
{
"FromPort": 443,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6788,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
},
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
]
}
您选择的迭代 .IpPermissions[] | .IpRanges[]
产生的结果与这些数组中的项目一样多。对于每个 true
结果,您的 select
传递有问题的输入(可能多次)。您需要像 any
或 all
这样的聚合器将所有结果组合成一个布尔结果,这样 select
就可以传递相应输入的 1 个或 0 个副本。
此外,您在 and
的 两边 迭代 .IpPermissions[]
在您的条件下,这将产生结果的笛卡尔积。
如果 .IpPermissions
数组中有 至少一个 项目与 .FromPort
并且至少有一个 与 .IpRanges
数组中的 .CidrIp
匹配:
jq '
.SecurityGroups[] | select(
any(.IpPermissions[]; .FromPort == 80 and
any(.IpRanges[]; .CidrIp == "0.0.0.0/0")
)
)
' data.json
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
你可以适当的使用括号()
和and
来过滤,像这样:(.FromPort==80 and (.IpRanges[] | .CidrIp=="0.0.0.0/0" ))
。通过这样做,我们确保两个条件都与IpPermissions
.
过滤器
.SecurityGroups | map(select(.IpPermissions[]
| (.FromPort==80 and (.IpRanges[] | .CidrIp=="0.0.0.0/0" ))))
输入
{
"SecurityGroups": [
{
"GroupName": "Group1",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
}
]
},
{
"GroupName": "Group2",
"IpPermissions": [
{
"FromPort": 443,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6788,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
},
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
]
}
输出
[
{
"GroupName": "Group3",
"IpPermissions": [
{
"FromPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
},
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"FromPort": 6789,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "1.2.3.4/24"
}
]
}
]
}
]
现在只能看到输出了Group3
演示
https://jqplay.org/s/qZvARp_5LE
或者您可以按照 pmf 的建议使用 any/2
。
过滤器
.SecurityGroups[]
| select(any(.IpPermissions[]; .FromPort==80
and any(.IpRanges[]; .CidrIp=="0.0.0.0/0")))
演示