skip to Main Content

I’m working with a JSON object having the following structure:

{
  "key-foo-1.0": [
    {
      "key1": "foo",
      "key2": "bar",
      "id": "01"
    },
    {
      "key1": "foo",
      "key2": "bar",
      "id": "23"
    }
  ],
  "key-bar-1.0": [
    {
      "key1": "foo",
      "key2": "bar",
      "id": "45"
    },
    {
      "key1": "foo",
      "key2": "bar",
      "id": "67"
    }
  ],
  "key-baz-1.0": [
    {
      "key1": "foo",
      "key2": "bar",
      "id": "89"
    }
  ]
}

I want to get all the id values where the "parent" key name matches the pattern .*foo.* or .*bar.*.

So in my example something like this:

cat json | jq <some filter> 
01
23
45
67

Based on https://unix.stackexchange.com/questions/443884/match-keys-with-regex-in-jq I tried:

$ cat json | jq 'with_entries(if (.key|test(".*foo.*$")) then ( {key: .key, value: .value } ) else empty end )'
{
  "key-foo-1.0": [
    {
      "key1": "foo",
      "key2": "bar",
      "id": "01"
    },
    {
      "key1": "foo",
      "key2": "bar",
      "id": "23"
    }
  ]
}

But I don’t really know how to continue.

I also think there is a better/simpler solution.

2

Answers


  1. you can use the following JQ expression:

    jq 'to_entries[] | select(.key | test(".*foo.*|.*bar.*")) | .value[] | .id'
    

    JQ playground example

    Login or Signup to reply.
  2. You could go with:

    jq -r '.[keys_unsorted[] | select(test(".*foo.*|.bar.."))][].id'
    
    01
    23
    45
    67
    

    This gathers all keys using keys_unsorted, then selects those matching the regular expression in test. The wrapping .[…] descends into them, the following [] iterates over the children, and .id outputs the values as raw text using the -r flag.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search