Reputation: 5663
I'm having difficulty using jq (1.5)
to parse deeply nested JSON structures, and I feel like I'm using it wrong. Take this example JSON input:
{
"a":[],
"b":[
{"x":"bar", "s":"FX", "f":["blorg","blarg","blurb"], "v":true},
{"x":"bar", "s":"EX", "f":["blorg","blarg","bloob"], "v":false},
{"x":"bar", "s":"XT", "f":["blorg","blart","bloop"], "v":true},
{"x":"bar", "s":"IJ", "f":["blorg","bleep","glarp"], "v":true},
{"x":"foo", "s":"IX", "f":["porg","parg","pork","peep"], "v":true},
{"x":"baz", "s":"AB", "f":["zing","zang","zoop"], "v":false}
],
"c":[]
}
To extract objects in list b
where x
is "bar" is straightforward:
jq '.["b"][] | select(.x == "bar")' < file.json
To restrict further to an object with a particular value of s
is also simple:
jq '.["b"][] | select(.x == "bar" and .s == "FX")' < file.json
If I want to apply a regular expression test, though, or any other test that requires a string input (bearing in mind that I still need object outputs), I think I have no choice but to chain filters. For example ...
To restrict to objects where s
ends in "X", unfortunately the following isn't a thing in jq
:
jq '.["b"][] | select(.x == "bar" and .s.endswith("X"))' < file.json
Instead I think I have to do this:
jq '.["b"][] | select(.x == "bar") | select(.s | endswith("X"))' < file.json
Similarly with s
contains "X":
jq '.["b"][] | select(.x == "bar") | select(.s | test("X"))' < file.json
Which is fine if I'm always doing boolean AND
s, but what if I want to do an OR
? For example, what is the jq
program to get objects where x
is "bar" OR
s
ends in "X"? Does jq
have an |OR|
filter?
jq '.["b"][] | select(.x == "bar") |OR| select(.s | endswith("X"))' < file.json
Or am I just doing it wrong? Am I attempting to reinvent some standard jq
algorithm for selecting objects?
Upvotes: 1
Views: 127
Reputation: 92874
Straightforwardly (specify all of your conditions within select
function):
jq -c '.b[] | select(.x == "bar" or (.s | endswith("X")))' file.json
The output:
{"x":"bar","s":"FX","f":["blorg","blarg","blurb"],"v":true}
{"x":"bar","s":"EX","f":["blorg","blarg","bloob"],"v":false}
{"x":"bar","s":"XT","f":["blorg","blart","bloop"],"v":true}
{"x":"bar","s":"IJ","f":["blorg","bleep","glarp"],"v":true}
{"x":"foo","s":"IX","f":["porg","parg","pork","peep"],"v":true}
Upvotes: 2