Use the select filter of jq:
jq '.zk_kafka | .[] | select(.InstanceType == "t2.medium")'
Use the --arg option to pass an argument to the query to avoid injections.
jq --arg instance "t2.medium" '.zk_kafka | .[] | select(.InstanceType == $instance)'
jq has a manual, a tutorial and a cookbook.
Use the select filter of jq:
jq '.zk_kafka | .[] | select(.InstanceType == "t2.medium")'
Use the --arg option to pass an argument to the query to avoid injections.
jq --arg instance "t2.medium" '.zk_kafka | .[] | select(.InstanceType == $instance)'
jq has a manual, a tutorial and a cookbook.
Alternatively, you can also use map():
jq '.zk_kafka | map(select(.InstanceType == "t2.medium"))' input.json
Very close! In your select expression, you have to use a pipe (|) before contains.
This filter produces the expected output.
. - map(select(.Names[] | contains ("data"))) | .[] .Id
The jq Cookbook has an example of the syntax.
Filter objects based on the contents of a key
E.g., I only want objects whose genre key contains "house".
$ json='[{"genre":"deep house"}, {"genre": "progressive house"}, {"genre": "dubstep"}]' $ echo "$json" | jq -c '.[] | select(.genre | contains("house"))' {"genre":"deep house"} {"genre":"progressive house"}
Colin D asks how to preserve the JSON structure of the array, so that the final output is a single JSON array rather than a stream of JSON objects.
The simplest way is to wrap the whole expression in an array constructor:
$ echo "$json" | jq -c '[ .[] | select( .genre | contains("house")) ]'
[{"genre":"deep house"},{"genre":"progressive house"}]
You can also use the map function:
$ echo "$json" | jq -c 'map(select(.genre | contains("house")))'
[{"genre":"deep house"},{"genre":"progressive house"}]
map unpacks the input array, applies the filter to every element, and creates a new array. In other words, map(f) is equivalent to [.[]|f].
Here is another solution which uses any/2
map(select(any(.Names[]; contains("data"))|not)|.Id)[]
with the sample data and the -r option it produces:
cb94e7a42732b598ad18a8f27454a886c1aa8bbba6167646d8f064cd86191e2b
a4b7e6f5752d8dcb906a5901f7ab82e403b9dff4eaaeebea767a04bac4aada19
filter array of objects using jq from json - Unix & Linux Stack Exchange
How do I filter the contents of a json array, but keep the parent with jq? - Unix & Linux Stack Exchange
json - How to filter array of objects by element property values using jq? - Stack Overflow
JQ - filter datasets in array based on index value within each dataset of array.
Videos
If "rebuilding" your structure is an option you could do something like this
jq '.Vpcs[]|select(.OwnerId!="abc")|{Vpcs: [.]}'
You could also use del() as:
jq 'del(.Vpcs[]|select(.OwnerId == "abc"))'
Or:
jq 'del(..|select(.OwnerId? == "abc"))'
To delete objects that have a OwnerId attribute set to "abc" wherever they are in the JSON data.
Note that would change {"key":{"OwnerId":"abcd"}} to {}. The "key" is also lost there.
From the docs:
jq '.[] | select(.id == "second")'Input
[{"id": "first", "val": 1}, {"id": "second", "val": 2}]Output
{"id": "second", "val": 2}
I think you can do something like this:
jq '.theList[] | select(.id == 2 or .id == 4)' array.json
You could use select within map.
.theList | map(select(.id == (2, 4)))
Or more compact:
[ .theList[] | select(.id == (2, 4)) ]
Though written that way is a little inefficient since the expression is duplicated for every value being compared. It'll be more efficient and possibly more readable written this way:
[ .theList[] | select(any(2, 4; . == .id)) ]
hmm, i managed to do it with this:
.[] | select(.foo as $tmpvar | ["aaa", "bbb"] | index ($tmpvar ) )
https://jqplay.org/s/g7AyRgARdU
According to this answer:
https://stackoverflow.com/a/46470951/2244766
in versions above 1.5 there is a new IN operator that makes life a bit easier:
.[] | select(.foo|IN("aaa","bbb"))
The SQL-style operators don't work well for me as a straight-forward selection mechanism; I believe they have a very specific use-case, for which they are uniquely suitable for, and for anything else they're (at best) clunky. At least that's been my experience. And I haven't really figured out what that specific use-case is, either.
With all of that as a backdrop, my recommendation is to use a simple regex test:
map(select(.foo | test("aaa|bbb")))
Given the example JSON:
<~> $ jq . /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "ccc",
"bar": 222
},
{
"foo": "aaa",
"bar": 333
},
{
"foo": "ddd",
"bar": 444
}
]
the above filter would result in:
<~> $ jq 'map(select(.foo | test("aaa|bbb")))' /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "aaa",
"bar": 333
}
]
If you need to generate the regex based on other data within the JSON, you can do that, too:
. as $data | map(select(.bar==111) | .foo) | join("|") as $regex | . = $data | map(select(.foo | test($regex)))
which would result in:
<~> $ jq '. as $data | map(select(.bar==111) | .foo) | join("|") as $regex | . = $data | map(select(.foo | test($regex)))' /tmp/so4229.json
[
{
"foo": "aaa",
"bar": 111
},
{
"foo": "bbb",
"bar": 111
},
{
"foo": "aaa",
"bar": 333
}
]
There may be a better way to run through the JSON twice (once to get the regex values, once to use it).