Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter keys by name, then access nested object using jq

Tags:

json

key

filter

jq

Novice jq user here, struggling with the following:

I have the following json and need to filter keys based on a keyword and print out the whole object (not just the key) or certain key/value pairs. Note the nested object structure of the JSON, which is intentional.

{
  "timers": {
    "timerWithAKeywordAPlusBlah": {
      "count": 1,
      "max": 0,
      "min": 0      
    },
    "timerWithAKeywordB": {
      "count": 2,
      "max": 0
    },
    "timerWithAKeywordAPlusBlahBlah": {
      "count": 2385,
      "max": 2,
      "min": 1         
    }
  }
}

Desired output:

"timerWithAKeywordAPlusBlah": {
  "count": 1,
  "max": 0,
  "min": 0
},
"timerWithAKeywordAPlusBlahBlah": {
  "count": 2385,
  "max": 2,
  "min": 1
}

Things I tried:

I can print out the key name, but can't figure out how to access the whole object.

cat timers.json| jq '.timers | keys[] | select(contains("KeywordA")) '
like image 426
lazy_tester Avatar asked Jun 14 '18 19:06

lazy_tester


People also ask

What is jq filter?

A jq program is a "filter": it takes an input, and produces an output. There are a lot of builtin filters for extracting a particular field of an object, or converting a number to a string, or various other standard tasks.

What is jq slurp?

The slurp option ( -s ) changes the input to the jq program. It reads all the input values and build an array for the query input. Using with the raw input option ( -R ) means reading the entire input as a string. The inputs function is a special stream that emits the remaining JSON values given to the jq program.


1 Answers

In this response, I'm going to assume that you want the output to be valid JSON. If you want the output to be in some other form, you can simply tack on some additional filters.

Anyway, the trick is to select the objects, not the keys, like so:

.timers
| with_entries( select(.key|contains("KeywordA") ) )

With your (modified) input, this produces:

{
  "timerWithAKeywordAPlusBlah": {
    "count": 1,
    "max": 0,
    "min": 0
  },
  "timerWithAKeywordAPlusBlahBlah": {
    "count": 2385,
    "max": 2,
    "min": 1
  }
}

You can then extract whatever details are ultimately required.

like image 133
peak Avatar answered Oct 05 '22 13:10

peak