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 - jqprogram, 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- jqthat 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 - idfields
 
- It outputs the value of the - idfield if the value is "13"
 
 
- It counts the length of the array, which is the number of the - idfields 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 bashconstructs 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 jqfilter, because it is going to process the entire input (that is just how it works) and theselectfilter 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" ]]