Skip to main content

Raymii.org Raymii.org Logo

Quis custodiet ipsos custodes?
Home | About | All pages | Cluster Status | RSS Feed | Gopher

Get a JSON value with bash and sed

Published: 26-02-2019 | Author: Remy van Elst | Text only version of this article


❗ This post is over two years old. It may no longer be up to date. Opinions may have changed.

Recently I was asked to get one value from a json object using only shell tools. The json in question is from a dutch radio station and it lists the current song that is played. Using this together with a few shell commands and notify- send we can show the current song when it changes as a desktop notification. I'd rather use Python or jq if it has to be shell. In this case the co-worker asked to just use simple shell tools and no external dependencies.

Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.

You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days.

This is the json file, formatted:

# curl -s 'https://api.grootnieuwsradio.nl/playing.json'
{
    "Stream_information":{
        "Name":"grootnieuws_ipad",
        "NameByClient":"grootnieuwsradio_website_aac",
        "Limit":"2000",
        "Account":"calculation",
        "IncomingSignal":"offline",
        "SecureTokenSharedSecret":"",
        "SecureTokenQueryParametersPrefix":"",
        "SecureTokenIncludeClientIPInHash":"false",
        "MultiBitrateEnable":"false",
        "DVREnable":"false",
        "PlayIPWhiteList":"",
        "PublishIPWhitelist":"",
        "SimultaneousConnections":"1729",
        "Auto_recording":"off",
        "PlayingNow":"Joke Buis - Welk Een Vriend Is Onze Jezus",
        "Encoder_visitors_statistics":{
            "REST_URI":"https:\/\/api.streampartner.nl\/grootnieuws_ipad\/stream_information\/encoder_visitors_statistics",
            "Options":[
                "GET"
            ]
        }
    }
}

The field we want is the PlayingNow field. Using sed, a regular expression with a backreference (\1) it can be shown:

sed -n 's|.*"PlayingNow":"\([^"]*\)".*|\1|p'

Example output:

curl -s 'https://api.grootnieuwsradio.nl/playing.json' | sed -n 's|.*"PlayingNow":"\([^"]*\)".*|\1|p'

Joke Buis - Welk Een Vriend Is Onze Jezus

The full script to send the desktop notifications:

#!/bin/bash
PATH="/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH"
if [[ ! -f /tmp/gnr-prev.txt ]]; then touch /tmp/gnr-prev.txt; fi
PREVSONG="$(cat /tmp/gnr-prev.txt)"
curl -s 'https://api.grootnieuwsradio.nl/playing.json' | sed -n 's|.*"PlayingNow":"\([^"]*\)".*|\1|p' > /tmp/gnr-cur.txt
CURSONG="$(cat /tmp/gnr-cur.txt)"
if [[ "$PREVSONG" != "$CURSONG" ]]; then
    mv /tmp/gnr-prev.txt /tmp/gnr.$(date +%s).txt;
    mv /tmp/gnr-cur.txt /tmp/gnr-prev.txt;
    notify-send "GNR: $CURSONG";
fi

Put it in cron for regular execution. Add this to your crontab as well if you use KDE:

DISPLAY=:0.0
XAUTHORITY=/home/remy/.Xauthority

Replace remy with your username.

Tags: bash , bash-bits , curl , json , python , sed , shell , snippets