Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using jq to extract values in JSON array with a particular key boolean == true?

Tags:

json

jq

So I have a JSON blob as below:

[
  {
    'id': 'something',
    'isSparse': true
  },
  ...
]

How do I write a jq command that'll filter out this JSON blob and print me the IDs of all entries in the array that have isSparse == true?

I tried the following:

cat <blob> | jq -c '.[] | select(.operational | contains("true"))'

but get the following, because obviously true is a boolean and not a string:

jq: error: boolean and string cannot have their containment checked.

like image 889
r123454321 Avatar asked Mar 09 '16 23:03

r123454321


People also ask

What is jq in JSON?

jq is a lightweight and flexible command-line JSON processor. It is like sed for JSON data – you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text. jq is a fantastic command-line JSON processor.

What is the use of jq command?

The JQ command is used to transform JSON data into a more readable format and print it to the standard output on Linux. The JQ command is built around filters which are used to find and print only the required data from a JSON file.

What is a 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.


3 Answers

If the task is to "print the IDs of all entries in the array that have isSparse == true", an appropriate jq filter would be:

.[] | select(.isSparse == true) | .id

If there is any possibility of duplicate .id values, then the following could be used to ensure only distinct values are emitted:

map( select(.isSparse == true) | .id ) | unique[]

As @JeffMercado pointed out, if .isSparse is strictly boolean, then select(.isSparse) would suffice.

like image 70
peak Avatar answered Sep 24 '22 20:09

peak


I add this answer as it may be helpful in future for a related scenario. - A specific example of this would be accessing a poorly written API which returns the same key/value pair differently depending on which endpoint or filters were used. This is highly annoying when interfacing, and the value is a string sometimes and a boolean at other times (furthermore, sometimes even a number, or a number as a string :| )


Adding | tostring will compare the value as desired;

cat <blob> | jq -c '.[] | select(.isSparse | tostring | contains("true"))'

or for an exact match, slight variant:

cat <blob> | jq -c '.[] | select((.isSparse | tostring) == "true")'

like image 28
hmedia1 Avatar answered Sep 24 '22 20:09

hmedia1


I assume you mean isSparse. The select filter takes in something that evaluates to a boolean value. isSparse is already a boolean so you just need to select it. contains is used for checking if something is in another container (a string, array, object, etc.).

$ jq -c '.[] | select(.isSparse)' <blob>
like image 45
Jeff Mercado Avatar answered Sep 21 '22 20:09

Jeff Mercado