问题描述
我有这个数据:
{
"cidr" : "X.X.X.X/27","defaultGateway" : "X.X.X.X","full" : false,"id" : "X.X.X.X","ipAddresstab" : [
{
"alias_domain" : null,"alias_name" : null,"description" : "This is the network address for X.X.X.X/27","dnr_rr" : null,"dns_domain" : null,"environnement" : null,"fdqn" : null,"hostname" : null,"ip" : "X.X.X.X","requester" : null,"status" : "reserved","type" : "network"
},{
"alias_domain" : null,"description" : "This is the default gateway address for X.X.X.X/27","type" : "gateway"
},{
"alias_domain" : "toto.com","alias_name" : "","description" : "this is a test","dns_domain" : "","environnement" : "test","fdqn" : "XXX","hostname" : "XXX","requester" : "XXX","status" : "allocated","type" : "VM"
},{
"ip" : "X.X.X.X","status" : "reserved"
},"description" : "This is the broadcast address for X.X.X.X/27","type" : "broadcast"
}
]
}
我想将所有状态“保留”更改为“可用”,而不更改具有网络、网关或广播状态的 ip 的状态。因此,使用 jq 我可以选择我需要的所有内容,而无需选择带有网络、网关或广播的 IP 作为状态并将状态更改为可用:
cat myfile | jq '.ipAddresstab[] | select(.status == "reserved") | select(.type != "network") | select(.type != "gateway") | select(.type != "broadcast") | .status = "available"'
输出:
{
"ip": "X.X.X.X","status": "available"
}
{
"ip": "X.X.X.X","status": "available"
}
{
"cidr" : "X.X.X.X/27","status" : "available"
},"type" : "broadcast"
}
]
}
解决方法
对于此类问题,|= 是您的朋友。
您可以选择一种直接的方法,例如:
.ipAddressTab
|= map(if .status == "reserved"
and .type != "network"
and .type != "gateway"
and .type != "broadcast"
then .status = "available" else . end)
或更微妙的:
(.ipAddressTab[]
| select(.status == "reserved" and
.type != "network" and
.type != "gateway" and
.type != "broadcast")
).status = "available"
顺便说一句,可以通过使用 IN
获得任一方法的 DRYer 版本:
.type | IN("network","gateway","broadcast") | not