Home > database >  jq - get dict element based on key regex
jq - get dict element based on key regex

Time:02-04

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.

CodePudding user response:

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.

CodePudding user response:

you can use the following JQ expression:

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

JQ playground example

  • Related