Daniel Porteous
Daniel Porteous

Reputation: 6333

Print key if any nested value matches a set value

This is best explained with expected input and output.

Given this input:

{
  "27852380038": {
    "compute_id": 34234234,
    "to_compute": [
      {
        "asset_id": 304221854,
        "new_scheme": "mynewscheme",
        "original_host": "oldscheme1234.location.com"
      },
      {
        "asset_id": 12123121,
        "new_scheme": "myotherscheme",
        "original_host": "olderscheme1234.location.com"
      }
    ]
  },
  "31352333022": {
    "compute_id": 43888877,
    "to_compute": [
      {
        "asset_id": 404221555,
        "new_scheme": "mynewscheme",
        "original_host": "oldscheme1234.location.com"
      },
      {
        "asset_id": 52123444,
        "new_scheme": "myotherscheme",
        "original_host": "olderscheme1234.location.com"
      }
    ]
  }
}

And the asset_id that I'm searching for, 12123121, the output should be:

27852380038

So I want the top level keys where any of the asset_ids in to_compute match my input asset_id.

I haven't seen any jq example so far that combines nested access with an any test / if else.

Upvotes: 3

Views: 159

Answers (2)

peak
peak

Reputation: 116650

The task can be accomplished without using environment variables, e.g.

< input.json jq -r --argjson ASSET_ID 12123121 '
  to_entries[]
  | {key, asset_id: .value.to_compute[].asset_id}
  | select(.asset_id==$ASSET_ID)
  | .key'

or more efficiently, using the filter:

to_entries[]
| select( any( .value.to_compute[]; .asset_id==$ASSET_ID) )
| .key

Upvotes: 2

Daniel Porteous
Daniel Porteous

Reputation: 6333

With some help from a coworker I was able to figure it out:

$ export ASSET_ID=12123121
$ cat input.json | jq -r "to_entries[] | .value.to_compute[] + {job: .key} | select(.asset_id==$ASSET_ID) | .job"
27852380038

Upvotes: 1

Related Questions