BlogJavaScript Object Notation (JSON) mit JQ filtern

JavaScript Object Notation (JSON) mit JQ filtern

Interagierst du bei den großen Public-Cloud-Anbietern AWS oder Azure in der einen oder anderen Weise mit den REST-APIs der jeweiligen Services, ist immer das JSON-Format bei der Kommunikation mit solchen APIs beteiligt. Darüber hinaus gibt es noch viele andere Einsatzbereiche von JSON. Daher ist es nützlich, mit den gängigen Abfrage-Tools für JSON vertraut zu sein. Nach JSON Path und JMSPath widmen wir uns mit JQ dem mächtigsten Tool in Trio, bleiben aber aufgrund der Vielzahl an Möglichkeiten vorerst bei den Basics.

Jq basiert auf dem Konzept von Filtern, die über einen JSON-Stream arbeiten. Jeder Filter nimmt eine Eingabe entgegen und gibt JSON an die Standardausgabe aus. Dabei gibt es zahlreiche vordefinierte Filter, die du verwenden kannst. Darüber hinaus kannst du solche Filter problemlos mit Pipes kombinieren, um schnell komplexe Operationen und Transformationen auf JSON-Daten erstellen und anwenden zu können.

Zuerst muss jq installiert werden. Zwar verfügen die meisten Programmiersprachen über Bibliotheken oder Module, die das Analysieren von JSON-Daten erlauben, leider gilt das gerade nicht für die BASH. Mit jq dagegen kannst du JSON einfach in der Bash-Shell parsen oder sogar XML in JSON konvertieren. Das Installieren von jq für die gängigen Linux-Distributionen ist simpel: Verwende bei Ubuntu:

sudo apt-get install jq

und bei Red Hat/CentOS …

sudo dnf install jq

Es ist auch möglich, die Binärdatei direkt herunterzuladen oder aus den Quellen zu übersetzen. Zum Überprüfen der Installation rufe jq einfach ohne Parameter auf:

Schauen wir uns mit dem Identitätsfilter ‚.‘ zunächst den einfachsten Filter von allen an, der übrigens eine der nützlichsten und am häufigsten verwendeten Funktionen von jq ist:

echo '{"auto":{"name":"audi","farbe":"silber","preis":50000}}' | jq '.'

Hier gib einen einfachen JSON-String als Echo zurück und leite ihn direkt an das jq-Kommando weiter. Dann verwende den Identitätsfilter „.“. Dieser übernimmt die Eingabe übernimmt und gibt sie unverändert als Ausgabe aus, mit der Einschränkung, dass jq die Ausgabe standardmäßig farbig formatiert.

Der Identitätsfilter gibt die Eingabe unverändert, aber „farbig“ aus

Du kannst diesen Filter auch direkt auf eine JSON-Datei anwenden:

jq '.' auto.json

Die Möglichkeit, JSON zu verschönern, ist besonders dann nützlich, wenn du Daten von einer API abrufen und die Antwort in einem klaren, lesbaren Format anzeigen möchtest, wie das z. B. beim Cloud Computing der Fall ist. Es gibt aber auch zahllose öffentlich zugängliche APIs mit denen du experimentieren kannst.

So liefert z. B.

curl http://api.open-notify.org/iss-now.json | jq '.'

die aktuelle Position der Internationalen Raumstation ISS:

Die aktuelle Position der ISS

Rufe doch analog zu unserem Artikel über JMSPath die Lister aller aktuellen virtuellen Maschinen im zuvor authentifizierten Azure-Konto ab:

az vm list | jq

Auflisten aller virtueller Maschinen in Azure

Dabei kannst du auf Eigenschaftswerte zugreifen, indem du einen anderen einfachen Filter, den .field-Operator. verwendest. Um einen Eigenschaftswert zu finden, kombiniere einfach diesen Filter gefolgt vom Eigenschaftsnamen. Teste das anhand unseres einfachen Auto-Datei-Beispiels:

jq  ´.auto´ auto.json

Du kannst Eigenschaftswerte auch miteinander verketten, womit du auf verschachtelte Objekte zugreifen kannst:

jq '.auto.farbe' auto.json

Wenn du mehrere Schlüssel abrufen musst, kannst du diese durch ein Komma trennen:

jq '.auto.farbe,.auto.preis' auto.json

Enthält eine der Eigenschaften Leerzeichen oder Sonderzeichen, musst du den Eigenschaftsnamen in Anführungszeichen setzen.

Arbeiten mit Arrays

Schauen wir uns nun an, wie du mit Arrays in JSON-Daten arbeiten kannst. Normalerweise verwendest du Arrays, um eine Liste von Elementen darzustellen. Wie bei vielen Programmiersprachen verwendet jq eckige Klammern, um den Anfang und das Ende eines Arrays zu kennzeichnen. Folgendes Beispiel zeigt, wie du über ein Array iterierst:

echo '["a","b","c"]' | jq '.[]'

Ein paar einfache Filter mit jq

Erstelle nun eine Liste mit Autos als JSON-Dokument:

[

  {

    "name": "audi",

    "farbe": "silber",

    "preis": 50000

  },

  {

    "name": "dacia",

    "farbe": "braun",

    "preis": 10000

  },

  {

    "name": "opel",

    "farbe": "weiss",

    "preis": 20000

  }

]

Hierbei ist jedes Element im Array ein Objekt, das eine Auto darstellt. Nun kannst du z. B. den Namen jedes Autos aus jedem Objekt im Array extrahieren:

jq '.[] | .name' autos.json

Das Kommando iteriert zuerst mit .[] über das gesamte Array. Danach übergibt es jedes Objekt im Array via Pipe (|) an den nächsten Filter im Befehl. Im letzten Schritt wird mit „.name“ das Namensfeld jedes Objekts ausgegeben: Alternativ kannst du mit

jq '.[].name' autos.json

auch direkt auf die Eigenschaft für jedes Objekt im Array zugreifen. Und wie bei allen Arrays kannst du auch direkt auf eines der Elemente im Array zugreifen, indem du den jeweiligen Index übergibst:

jq '.[2].preis' autos.json

Zwei Schreibweisen, die letztendlich das Gleiche tun

Funktionen nutzen

Eigentlich ist jq viel mehr als ein Filter und verfügt über viele leistungsstarke integrierte Funktionen, mit denen du eine Vielzahl nützlicher Operationen ausführen kannst. Eine dieser praktischen Funktionen für Arrays und Objekte ist die Längenfunktion. Diese kannst du nutzen, um die Länge des Arrays oder die Anzahl der Eigenschaften eines Objekts zurückzugeben:

jq '.autos | length' autos.json

Mit den Funktionen „min“ und „max“ hingegen findest du schnell das minimale oder maximale Element eines Eingabe-Arrays:

Mit der Funktion „test“ kannst du dagegen prüfen, ob eine Eingabe mit einem bestimmten regulären Ausdruck übereinstimmt: Folgendes Beispiel gibt den Preis sämtlicher Autos aus, deren Name mit dem Buchstaben „a“ beginnt.

Ein weiterer häufiger Anwendungsfall besteht darin, eindeutige Vorkommen eines bestimmten Werts in einem Array zu ermitteln oder Duplikate zu entfernen. Folgendes Beispiel prüft, wie viele einzigartige Farben das autos-Dokument enthält:

Jq bringt sogar viele leistungsfähige eingebaute Funktionen mit:

Schließlich unterstützt jq auch das Slicing von Arrays. Dies ist besonders nützlich, wenn Sie ein Sub-Array eines Arrays zurückgeben müssen.

echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[6:9]'

In diesem Beispiel ist das Ergebnis ein neues Array mit einer Länge von 3, das die Elemente von Index 5 (einschließlich) bis Index 8 (exklusiv) enthält:

Es ist ebenfalls möglich, einen der Indizes wegzulassen:

echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[:5]' | jq '.[-2:]'

Wie viele moderne Programmiersprachen beherrscht jq sogar Slicing

Schulungen die dich interessieren könnten

Bewertungen

Kundenstimme
Dimitri B.
HSBC Trinkaus
star-participantstar-participantstar-participantstar-participantstar-participant
Sehr informativ und in der Praxis wiederverwendbar.
Kundenstimme
Martin S.
Bundeseisenbahnvermögen
star-participantstar-participantstar-participantstar-participantstar-participant
Das Training zeichnet sich durch einen sehr hohen Praxisbezug und Raum für individuelle Hilfe persönlicher Problemstellungen sowie durch einen engagierten und hoch kompetenten Trainer aus.
Kundenstimme
Torsten B.
Westdeutscher Rundfunk WDR
star-participantstar-participantstar-participantstar-participantstar-participant
Das Seminar hat nicht nur Spaß gemacht, sondern auch wirklich 'ne Menge gebracht :-)
Kundenstimme
Markus H.
CARAT Dreieich
star-participantstar-participantstar-participantstar-participantstar-participant
Der Trainer machte einen sehr netten und kompetenten Eindruck und ging auf unsere Wünsche und Anregungen sehr praxisorientiert ein .