papi
papi

Reputation: 237

check if specific string is in Json file via bash

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

Answers (3)

LeadingEdger
LeadingEdger

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

Old Pro
Old Pro

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:

  1. 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.

  2. It creates an array to capture the output of...

    1. It loops through the array, picking out all the id fields

    2. It outputs the value of the id field if the value is "13"

  3. It counts the length of the array, which is the number of the id fields whose value is "13"

  4. 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" ]]

Upvotes: 3

peak
peak

Reputation: 116700

Here is one possibility:

any(.[]; .id == "13")

Upvotes: 1

Related Questions