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
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.
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:
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
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
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:
"$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).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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With