{{tag>dev js json jq cli}} ====== La commande jq ====== La commande **jq** permet d'analyser (parser), valider, afficher et retravailler des objets **JSON**((**J**ava**S**cript **O**bject **N**otation)). L'utilitaire s’exécute en ligne de commande (CLI). ===== Mise en forme des objets JSON ===== Les objets JSON sont conçus pour l'échange d'informations en programmes. Ils ne sont pas aisément lisibles pour un lecteur humain: # Ici la position de la station ISS est retournée par l'API sous forme de données formatée en JSON curl -s http://api.open-notify.org/iss-now.json {"iss_position": {"longitude": "-152.6537", "latitude": "-51.4075"}, "message": "success", "timestamp": 1639219539} La commande **jq** introduit alinéas, retours à la ligne et coloration syntaxique pour faciliter la lisibilité et l'analyse des objets JSON: # enregistre l'objet JSON dans un fichier curl -s http://api.open-notify.org/iss-now.json > iss-postion.json # mise en forme de l'ojet JSON cat iss-position.json | jq { "iss_position": { "longitude": "-99.6042", "latitude": "-39.8896" }, "message": "success", "timestamp": 1639220152 } ===== Filtrer les attributs ===== **jq** permet de définir des filtres pour sélectionner les attributs à afficher: # sélectionner seulement l'attribut timestamp de l'objet cat iss-postion.json | jq .timestamp 1639220152 # Ici on récupère le timestamp et on le reformate via la commande date: TS=$(cat iss-postion.json | jq .timestamp) date --date="@$TS" sam. 11 déc. 2021 11:55:52 CET On peut définir un filtre sélectionnant plusieurs attributs: cat iss-postion.json | jq ".iss_position.longitude, .iss_position.latitude" "-99.6042" "-39.8896" # syntaxe équivalente: jq filtre fichier jq ".iss_position.longitude, .iss_position.latitude" iss-postion.json "-99.6042" "-39.8896" ===== Les tableaux ===== Pour l'exemple on utilise encore l'API de la NASA. Ici on récupère la liste des astronautes présent dans les différents vaisseaux en orbite: curl -s http://api.open-notify.org/astros.json > equipages.json L'objet JSON possède un attribut people de type tableau: # Sélectionner tous les éléments du tableau jq ".people[]" equipages.json # Sélectionner un élément via son index jq ".people[4]" equipages.json # Sélectionner plusieurs éléments par tranche (slice) ici les éléments 2 et 3 jq ".people[2:4]" equipages.json **jq** permet également de définir un nouvel objet de type tableau à partir des éléments filtrés: # On affiche l'objet initial: jq . iss-postion.json { "iss_position": { "longitude": "-99.6042", "latitude": "-39.8896" }, "message": "success", "timestamp": 1639220152 } # Créer un tableau de 3 éléments à partir de l'objet en entrée jq "[.timestamp, .iss_position.latitude, .iss_position.longitude]" iss-postion.json [ 1639220152, "-39.8896", "-99.6042" ] ===== Combiner les filtres ===== Il est possible de combiner des filtres via les pipes ''|'': # chaque élément du tableau contient deux paires dont les clés sont "craft" et "name" jq ".people[0]" equipages.json { "craft": "ISS", "name": "Mark Vande Hei" } # Ici on combine les filtres pour ne sélectionner que la clé "name": jq ".people[0] | .name" equipages.json "Mark Vande Hei" Pour les objets complexes on peut ainsi combiner les filtres pour sélectionner et travailler les éléments souhaités dans des tableaux: # On récupère la valeur de la clé "name" des 10 derniers éléments d'un tableau dans le fichier strike.json jq ".[-10:] | .[] | .name" strikes.json # On récupère les valeurs des clés "name" et "mass" des élements 450 à 454 jq ".[450:455] | .[] | .name, .mass" strikes.json ===== Usage des fonctions ===== ==== La fonction delete ==== On peut retirer un attribut via la commande delete: # Objet initial jq . iss-postion.json { "iss_position": { "longitude": "-99.6042", "latitude": "-39.8896" }, "message": "success", "timestamp": 1639220152 } # appel de la fonction delete produit une sortie sans la clé "message" jq "del(.message)" iss-postion.json { "iss_position": { "longitude": "-99.6042", "latitude": "-39.8896" }, "timestamp": 1639220152 } ==== La fonction length ==== La fonction length retourne la longueur des chaines, objets ou tableaux: # détermine la taille du tableau .people jq ".people | length" equipages.json 13 # on affiche le 13ième élément jq ".people[12]" equipages.json { "craft": "ISS", "name": "Yozo Hirano" } # L'élément contient 2 paires: craft et name de type chaines de caractères # on affiche la taille du 13ième élément, puis la taille des valeurs de chaque clé jq ".people[12] | length" equipages.json 2 jq ".people[12] | .[] | length" equipages.json 3 11 # équivalent jq ".people[12] | .craft | length" equipages.json 3 jq ".people[12] | .name | length" equipages.json 11 ==== La fonction keys ==== La fonction keys permet d'obtenir un tableau d'éléments listant les clés d'un objet en entrée: jq ".people[12] | keys" equipages.json [ "craft", "name" ] ==== La fontion has() ==== La fonction has() permet de déterminer si un objet contient une clé particulière: jq '.people[12] | has("firstname")' equipages.json false jq '.people[12] | has("name")' equipages.json true ===== Références ===== * https://www.howtogeek.com/529219/how-to-parse-json-files-on-the-linux-command-line-with-jq/ * https://stedolan.github.io/jq/manual/