Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

verify that a json field exists with jq and bash?

Tags:

json

bash

jq

I have a script that uses jq for parsing a json string MESSAGE (that is read from another application). Meanwhile the json has changed and a field is split in 2 fields: file_path is now split into folder and file. The script was reading the file_path, now the folder may not be present, so for creating the path of the file I have to verify if the field is there. I have search for a while on the internet, and manage to do:

echo $(echo $MESSAGE | jq .folder -r)$'/'$(echo $MESSAGE | jq .file -r)

if [ $MESSAGE | jq 'has(".folder")' -r  ]
then
        echo $(echo $MESSAGE | jq .folder -r)$'/'$(echo $MESSAGE | jq .file -r)
else
        echo $(echo $MESSAGE | jq .file -r)
fi

where MESSAGE='{"folder":"FLDR","file":"fl"}' or MESSAGE='{"file":"fl"}'

The first line is printing FLDR/fl or null/fl if the folder field is not present. So I have thought to create an if that is verifying if the folder field is present or not, but it seems that I am doing it wrong and cannot figure out what is wrong. The output is

bash: [: missing `]'
jq: ]: No such file or directory
null/fl
like image 292
sop Avatar asked Apr 10 '15 13:04

sop


People also ask

How to check if a certain key or value exists in JSON?

How to check if a certain key or value exists in JSON data using jq? How to check if a certain key or value exists in JSON data using jq? You can use jq in-built function has () and contains () to check if a certain key or value exists in your JSON data.

How do I understand JSON in Bash?

Bash doesn’t understand JSON out of the box, and using the typical text manipulation tools like grep, sed, or awk, gets difficult. Luckily there’s a better way using a tool called jq. jq can simplify the above bash to this:

What is JQ in Bash?

jq is a powerful tool that lets you read, filter, and write JSON in bash jq is a powerful tool that lets you read, filter, and write JSON in bash

How to check if a specific key or value exists in JQ?

You can use jq in-built function has () and contains () to check if a certain key or value exists in your JSON data. Here is a quick example for your reference


1 Answers

I'd do the whole thing in a jq filter:

echo "$MESSAGE" | jq -r '[ .folder, .file ] | join("/")'

In the event that you want to do it with bash (or to learn how to do this sort of thing in bash), two points:

  • Shell variables should almost always be quoted when they are used (i.e., "$MESSAGE" instead of $MESSAGE). You will run into funny problems if one of the strings in your JSON ever contains a shell metacharacter (such as *) and you forgot to do that; the string will be subject to shell expansion (and that * will be expanded into a list of files in the current working directory).
  • A shell if accepts as condition a command, and the decision where to branch is made depending on the exit status of that command (true if the exit status is 0, false otherwise). The [ you attempted to use is just a command (an alias for test, see man test) and not special in any way.

So, the goal is to construct a command that exits with 0 if the JSON object has a folder property, non-zero otherwise. jq has a -e option that makes it return 0 if the last output value was not false or null and non-zero otherwise, so we can write

if echo "$MESSAGE" | jq -e 'has("folder")' > /dev/null; then
    echo "$MESSAGE" | jq -r '.folder + "/" + .file'
else
    echo "$MESSAGE" | jq -r .file
fi

The > /dev/null bit redirects the output from jq to /dev/null (where it is ignored) so that we don't see it on the console.

like image 143
Wintermute Avatar answered Oct 23 '22 00:10

Wintermute