JQ:更改一些值并显示所有数据?



我有这个数据:

{
   "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,
         "alias_name" : null,
         "description" : "This is the default gateway 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" : "gateway"
      },
      {
         "alias_domain" : "toto.com",
         "alias_name" : "",
         "description" : "this is a test",
         "dns_domain" : "",
         "environnement" : "test",
         "fdqn" : "XXX",
         "hostname" : "XXX",
         "ip" : "X.X.X.X",
         "requester" : "XXX",
         "status" : "allocated",
         "type" : "VM"
      },
      {
         "alias_domain" : "toto.com",
         "alias_name" : "",
         "description" : "this is a test",
         "dns_domain" : "",
         "environnement" : "test",
         "fdqn" : "XXX",
         "hostname" : "XXX",
         "ip" : "X.X.X.X",
         "requester" : "XXX",
         "status" : "allocated",
         "type" : "VM"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "reserved"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "reserved"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "reserved"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "reserved"
      },
      {
         "alias_domain" : null,
         "alias_name" : null,
         "description" : "This is the broadcast 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" : "broadcast"
      }
   ]
}

我想更改所有状态"保留"作为"available"不改变状态为网络、网关或广播的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"
}
{
  "ip": "X.X.X.X",
  "status": "available"
}
{
  "ip": "X.X.X.X",
  "status": "available"
}

但是有一种方法可以做到这一点,以便得到这个输出:

{
   "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,
         "alias_name" : null,
         "description" : "This is the default gateway 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" : "gateway"
      },
      {
         "alias_domain" : "toto.com",
         "alias_name" : "",
         "description" : "this is a test",
         "dns_domain" : "",
         "environnement" : "test",
         "fdqn" : "XXX",
         "hostname" : "XXX",
         "ip" : "X.X.X.X",
         "requester" : "XXX",
         "status" : "allocated",
         "type" : "VM"
      },
      {
         "alias_domain" : "toto.com",
         "alias_name" : "",
         "description" : "this is a test",
         "dns_domain" : "",
         "environnement" : "test",
         "fdqn" : "XXX",
         "hostname" : "XXX",
         "ip" : "X.X.X.X",
         "requester" : "XXX",
         "status" : "allocated",
         "type" : "VM"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "available"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "available"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "available"
      },
      {
         "ip" : "X.X.X.X",
         "status" : "available"
      },
      {
         "alias_domain" : null,
         "alias_name" : null,
         "description" : "This is the broadcast 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" : "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:

获得任何一种方法的干燥器版本。
.type | IN("network", "gateway", "broadcast") | not

最新更新