Med cURL och jq går det att extrahera data från API:er direkt från kommandoraden. Jq är en JSON-tolkare och beskrivs av utvecklarna som sed och awk för JSON.

Arkiv Bild: Pexels

Här kommer vi att extrahera aktuell temperatur med tidsstämpel från SMHIs öppna API. Detta är samma API som vi använde i Pythonmiljö i Docker.

API:et vi kommer hämta temperaturen från är http://opendata-download-metobs.smhi.se/api/version/1.0/parameter/1/station/62180/period/latest-hour/data.json.

För att slippa ange den långa adressen till API:et varenda gång vi ska laborera med jq kommer vi att spara ner svaret i en variabel.

ANNONS

$> smhidata=$(curl -s http://opendata-download-metobs.smhi.se/api/version/1.0/parameter/1/station/62180/period/latest-hour/data.json) 

Skriver vi ut innehållet från variabeln är det oformaterad JSON, vilket är väldigt svårläst.

$> echo $smhidata
{"value":[{"date":1659776400000,"value":"16.0","quality":"G"}],"updated":1659776400000,"parameter":{"key":"1","name":"Lufttemperatur","summary":"momentanvärde, 1 gång/tim","unit":"degree celsius"},"station":{"key":"62180","name":"Ängelholm-Barkåkra Flygplats","owner":"...

Vi börjar därför med att skriva ut JSON-filen med hjälp av jq så att den blir snyggt formaterad. Vi skriver ut innehållet med echo $smhidata | jq. Början av innehållet ser ut som nedan (innehållet är längre än vad som visas här):

{
  "value": [
    {
      "date": 1659776400000,
      "value": "16.0",
      "quality": "G"
    }
  ],
  "updated": 1659776400000,
  "parameter": {
    "key": "1",
    "name": "Lufttemperatur",
    "summary": "momentanvärde, 1 gång/tim",
    "unit": "degree celsius"
  },
  "station": {
    "key": "62180",
    "name": "Ängelholm-Barkåkra Flygplats",
    "owner": "Ängelholm Helsingborgs flygplats Holding AB",
    "ownerCategory": "CLIMATE",
    "measuringStations": "CORE",
    "height": 2
  },

Det som vi är intresserade av är bara temperaturen och tidsstämpeln. Dessa ligger i den yttre nivån i value. Vi börjar därför med att skriva ut endast detta:

$> echo $smhidata | jq -r '.value'
[
  {
    "date": 1659776400000,
    "value": "16.0",
    "quality": "G"
  }
]

Temperaturen och tidsstämpeln ligger här på den andra nivån, det vill säga innanför []. För att komma åt dessa värden behöver vi således först ta oss ner den nivån. Det gör vi genom att lägga till just [] efter value:

$> echo $smhidata | jq -r '.value[]'
{
  "date": 1659776400000,
  "value": "16.0",
  "quality": "G"
} 

Nu kan vi fortsätta med att extrahera value, alltså temperaturen:

$> echo $smhidata | jq -r '.value[].value'
16.0

Tidsstämpeln kommer vi åt på samma sätt:

$> echo $smhidata | jq -r '.value[].date'
1659776400000

Notera dock att tidsstämpeln är i UNIX epoch time. Ett tidsformat som mäter antalet sekunder som förfallit sedan midnatt den 1 januari 1970 UTC. Men i detta fallet är formatet i millisekunder, vilket ställer till det vid omvandlingen till vanligt datumformat. Vi behöver därför först dividera talet med 1000 så att vi får det i sekunder. Till detta kan vi använda verktyget bc som står för Basic Calculator.

För att sedan omvandla från UNIX epoch time till vanligt datumformat använder vi date-kommandot. I Linux gör vi omvandlingen med date -d @$timestamp. Men under macOS använder vi istället date -r $timestamp.

$> timestamp=$(echo $smhidata | jq -r '.value[].date')
$> timestamp=$(echo "$timestamp / 1000" | bc)
$> date -d @$timestamp
lör  6 aug 2022 11:00:00 CEST

Vi kan också skriva ut flera fält samtidigt med jq. Vi behöver således inte skriva ut temperaturen och tidsstämpeln var för sig. Vi separar dem då med ett kommatecken.

$> echo $smhidata | jq -r '.value[].value, .value[].date'
16.0
1659776400000

Ett skript

Det är dags att sätta samman allting i ett skript. Här använder vi xargs för att göra hela omvandlingen från UNIX epoch time till vanligt datum på en och samma rad. xargs -I % talar om att vi vill föra in utdatan (tidsstämpeln utan millisekunder) vid platsen för procenttecknet, vilket här blir direkt efter @-tecknet för date-kommandot.

#!/bin/bash
PATH="/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin"

# Spara båda värdena till en variabel. De hamnar som en sträng efter varandra
smhidata=$(curl -s http://opendata-download-metobs.smhi.se/api/version/1.0/parameter/1/station/62180/period/latest-hour/data.json \
    | jq -r '.value[].value, .value[].date')

# Första fältet i strängen är temperaturen
temperature=$(echo $smhidata | awk '{ print $1 }')

# Andra fältet i strängen är tidsstämpeln
timestamp=$(echo $smhidata | awk '{ print $2 }')

# Skriv ut resultatet och fixa tidsstämpeln med xargs för att slippa dubbla rader
echo "$temperature grader ($(echo $timestamp / 1000 | bc | xargs -I % date -d @%))"

När vi kör ovanstående skript får vi följande resultat:

$> ./get-smhi-data.sh
17.1 grader (lör  6 aug 2022 14:00:00 CEST)

Du hittar mer information om jqstedolan.github.io/jq. Mer information om curl hittar du på curl.se. Det finns också mycket information i deras respektive manualsida, man jq och man curl. För mer information om bc och xargs, se man bc och man xargs. För mer information om awk se man awk.


Kommentarer

Kommentarsfältet är modererat. Det innebär att alla kommentarer granskas av ansvarig utgivare före publicering.

Du väljer själv om du vill ange ditt riktiga namn, en pseudonym eller vara helt anonym. Ingen registrering behövs.