Given the input json
[
{"title": "first line"},
{"title": "second line"},
{"title": "third line"}
]
How can we extract only the titles that contain keywords that are listed in a second "filter" array. Using a shell variable here for instance:
filter='["second", "third"]'
The output in this case would be
[
{"title": "second line"},
{"title": "third line"}
]
Also, how to use the array filter to negate instead. Eg: return only the "first line" entry in the previous example.
There is a similar reply but using an old version of jq. I hope that there's a more intuitive/readable way to do this with the current version of jq.
You can use a combination of jq
and shell tricks using arrays to produce the filter. Firstly to produce the shell array, use an array notation from the shell as below. Note that the below notation of bash
arrays will not take ,
as a separator in its definition. Now we need to produce a regex filter to match the string, so we produce an alternation operator
filter=("first" "second")
echo "$(IFS="|"; echo "${filter[*]}"
first|second
You haven't mentioned if the string only matches in the first or last or could be anywhere in the .title
section. The below regex matches for the string anywhere in the string.
Now we want to use this filter in the jq
to match against the .title
string as below. Notice the use of not
to negate the result. To provide the actual match, remove the part |not
.
jq --arg re "$(IFS="|"; echo "${filter[*]}")" '[.[] | select(.title|test($re)|not)]' < json