Note: when the question was closed, I added this answer to the question in an effort to get the question reopened:
(( $(jq < file.json '[.[].id | select(. == "13")] | length') > 0))
The OP said it was inefficient. I do not know why. Here is what it does:
It passes the JSON through the jq
program, which is a JSON parser. The bash shell has no native understanding of JSON, so any solution is going to make use of an external program. Other programs will treat JSON as text, and may work in some or most cases, but it is best to use a program like jq
that follows the formal JSON specification to parse the data.
It creates an array to capture the output of...
It loops through the array, picking out all the id
fields
It outputs the value of the id
field if the value is "13"
It counts the length of the array, which is the number of the id
fields whose value is "13"
Using native bash
, it converts that output into a number and evaluates to true if the number is greater than 0 and false otherwise.
I do not think you will find something significantly more efficient that formally follows the JSON spec.
- This only runs 1 program,
jq
, which is the de facto standard JSON processor. It is not part of the POSIX standard (which predates JSON) but it is the most likely JSON processor to be installed on a system.
- This uses native
bash
constructs to interpret the output and to the test.
- There is not going to be a solution that is more efficient because it runs zero programs (bash cannot do it alone) and there is not going to be a better program to use than
jq
.
- There is not going to be a significantly better
jq
filter, because it is going to process the entire input (that is just how it works) and the select
filter stops the processing of objects that fail the test, which is all or almost all of them.
The alternative "peak" suggests is more compact and more elegant (good things) but not significantly more (or less) efficient. It looks better in the post because a lot is left out. The full test would be
[[ $(jq < file.json 'any(.[]; .id == "13")') == "true" ]]
Actually, the .[];
generator is unnecessary, so the even more compact answer would be
[[ $(jq < file.json 'any(.id == "13")') == "true" ]]