我的JSON文件具有以下结构
[
{
"Header": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
},
{
"agentTechnologyType": "TOMCAT",
"entityId": "SERVICE-728B1FF49D132C89",
"serviceType": "WebRequest",
"webServerName": "www.example.com:80"
},
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-42A0FB8666B36EB4",
"serviceType": "Process"
},
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
我需要应用几个过滤器,并根据不同的标准留在.Body[]
数组对象中:
- 仅选择
.Body[]
数组中不存在.webServerName
键的这些对象-此条件应仅保留.Body[]
数组中的对象#2 - 仅在
.Body[]
数组中选择这些对象,其中.webServerName
的值为www.example.com:443
,这将留下对象#0.3 - 选择存在
.webServerName
键的所有对象,因此否定条件#1-这将保留除#2之外的所有对象
对于#1,下面的过滤器完成的工作
[.[].Header as $x | (.[].Body[] | select( (.webServerName == null ))) as $y | {Tenant: $x, Body: [$y]} ]
它给出以下输出:
[
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-42A0FB8666B36EB4",
"serviceType": "Process"
}
]
}
]
但当我试图修改条件#2 的过滤器时
[.[].Header as $x | (.[].Body[] | select( (.webServerName == "www.example.com:443" ))) as $y | {Tenant: $x, Body: [$y]} ]
这给了我以下输出——两个条目而不是一个条目。
[
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
},
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
而预期的输出应该看起来像案例#2:
[
{
"Tenant": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
},
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
对于案例#3,如下所示:
[
{
"Header": {
"Tenant": "T1"
},
"Body": [
{
"agentTechnologyType": "JAVA",
"entityId": "SERVICE-EDA448F07EDBDAA6",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
},
{
"agentTechnologyType": "TOMCAT",
"entityId": "SERVICE-728B1FF49D132C89",
"serviceType": "WebRequest",
"webServerName": "www.example.com:80"
},
{
"agentTechnologyType": "APACHE",
"serviceType": "WebRequest",
"webServerName": "www.example.com:443"
}
]
}
]
我试图弄清楚我在哪里犯了错误——在选择条件或最后形成新对象时。
根据您的需求判断,您似乎需要一个表达式来选择.Body[]
数组中.webServerName
密钥为www.example.com:443
或密钥基本存在的对象
.[].Body |= map(select(.webServerName == "www.example.com:443" or has("webServerName") ))
你的两次尝试虽然有效,但确实令人费解。有选择地过滤掉数组内对象的标准模式是将|=
运算符与正确的select
表达式一起使用。
| {Tenant: $x, Body: [$y]}
是错误的,因为它应用于在上一个表达式中筛选的2个对象中的每一个。因此,每个结果都创建了一个Tenant
字段。由于密钥名称没有更改(相同的密钥Tenant
(,因此实际上没有用{..}
重新创建新对象的目的。