Parsing JSON in Bash is never usually the best idea but sometimes it may be necessary or preferred. Here’s a nice easy script which uses the ‘jq’ command to perform JSON parsing in Bash.

Let’s imagine you have the following JSON which is outputted by a stats gathering process:
{"web_rate":1,"db_rate":2,"php_rate":2}
Parsing that in Bash by writing some regex’s etc is perfecting possible but there’s an infinitely easier way. Welcome to ‘jq’. Let’s see it in action.
In Ubuntu, simply install ‘jq’ with Apt:
sudo apt-get install jq
The following example is a script written for Nagios which will parse JSON from a file and extract the bits is needs.
For bonus points, spot the nifty use of ‘date’ to work out if the file has been modified within $UPDATERATE
[code language="bash"]
#!/bin/bash
############################################
WARN_WEB="20"
CRIT_WEB="40"
WARN_DB="20"
CRIT_DB="40"
WARN_PHP="20"
CRIT_PHP="40"
FILE="/var/www/html/rates/reqrate.txt"
UPDATERATE="2"
############################################
JQ="/usr/bin/jq"
EXIT=0
MODTIME=$(date -r $FILE +%s)
TIME=$(date +%s)
DIFF=$(($TIME - $MODTIME))
RATE_WEB=$($JQ .web_rate $FILE)
RATE_DB=$($JQ .db_rate $FILE)
RATE_PHP=$($JQ .php_rate $FILE)
if [ $DIFF -gt $UPDATERATE ]
then
echo "ERROR: File Not Updating ($DIFF seconds old)"
exit 2
fi
for SERVICE in WEB DB PHP ; do
RATE=RATE_$SERVICE
WARN=WARN_$SERVICE
CRIT=CRIT_$SERVICE
if [ ${!RATE} -ge ${!WARN} ] && [ ${!RATE} -lt ${!CRIT} ]
then
echo -n "WARN: $SERVICE Rate >= ${!WARN} (${!RATE}) "
if [$EXIT -lt 2 ] ; then EXIT="1" ; fi
elif [ ${!RATE} -ge ${!CRIT} ]
then
echo -n "CRIT: $SERVICE Rate >= ${!CRIT} (${!RATE}) "
EXIT="2"
else
echo -n "OK: $SERVICE (${!RATE}) "
fi
done
exit $EXIT
[/code]
I like this article because it is short and to the point. Keep up the good work!