Reputation: 237
Lets say this is my json file content:
[ { "id":"45" }, { "id":"56" }, { "id":"13" }, { "id":"5" } ]
and I want to find out if id "13" is in the json file.
Is there an way to do this in bash
?
I tried to run the command with jq and all sorts of different variations of it (with contain and without for example) and nothing answers this query for me.
Upvotes: 3
Views: 7778
Reputation: 704
Here is one simple way to to determine if a given "id" value is present using perl
:
echo '[ { "id":"45" }, { "id":"56" }, { "id":"13" }, { "id":"5" } ]' | perl -00 -lne 'if (/"id":"13"/) {print "true"} else {print "false"}'
true
echo '[ { "id":"45" }, { "id":"56" }, { "id":"13" }, { "id":"5" } ]' | perl -00 -lne 'if (/"id":"33"/) {print "true"} else {print "false"}'
false
Upvotes: 2
Reputation: 25547
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.
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.bash
constructs to interpret the output and to the test.jq
.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" ]]
Upvotes: 3