Aide-mémoire jq

Guy Lapalme, RALI-DIRO, Université de Montréal, décembre 2024

[English version of this document]

jq Est un outil de ligne de commande qui permet de manipuler des fichiers .json ou .jsonl pour les valider, les formater, en extraire des informations ou les transformer. On peut le considérer comme l'équivalent de sed ou awk pour les fichiers de texte dont les informations des lignes sont séparées par des tabulations. Le système est rapide et efficace pour traiter de gros fichiers, y compris en mode streaming.

Si le fichier d'entrée contient plusieurs objets JSON (c'est typiquement le cas avec les fichiers .jsonl), le programme est appliqué sur chaque objet et chaque résultat est produit séparément. Une option du programme (--slurp ou -s) permet de considérer tous les objets du fichier comme une liste d'objets. On peut donc y effectuer des opérations les combinant, par exemple un tri ou l'élimination de doublons.

La documentation officielle propose un tutoriel présentant quelques exemples ainsi qu’un manuel qui énumère toutes les fonctions illustrées par un court exemple, trop souvent simpliste. Cependant, le manuel n’explique pas comment enchaîner ces fonctions pour effectuer des tâches intéressantes.

La syntaxe des expressions jq est déroutante au début, car elle s’appuie sur la composition de filtres (point-free programming) plutôt que sur la notation fonctionnelle habituelle. jq est un langage de programmation doté de structures de contrôle, de variables, de fonctions et même de modules. Or, comme toutes mes applications jq se sont limitées à une seule expression sur la ligne de commande, ce document se concentrera sur cet aspect du langage. Ces expressions permettent tout de même d'effectuer des tâches utiles.

Il existe plusieurs tutoriels pour jq sur le web, dont celui-ci qui est excellent, mais maintenant truffé de publicités. Malheureusement, ces guides ne se concentrent pas suffisamment sur les aspects les plus utiles pour moi, à savoir l'extraction et la conversion de données JSON.

Ce document présente les concepts utilisés dans la programmation en jq et une liste des fonctions qui m'ont été les plus utiles. Ensuite, je donne quelques exemples d'expressions appliquées sur deux organisations de fichier: un avec une seule structure JSON et un autre en JSONL qui comprend plusieurs structures JSON. Je termine avec une liste de références que j'ai trouvé intéressantes parmi les centaines qu'on trouve, mais qui reprennent trop souvent les mêmes exemples simples.

Ce texte me servira de rappel, bien que je sois moins susceptible de m'en servir après l’avoir écrit. J'espère néanmoins qu'il sera bénéfique pour d'autres.

Concepts

Une expression jq est un filtre qui transforme une entrée en une ou plusieurs sorties. Tous les éléments du langage jq sont des filtres, même un nombre ou une chaîne qui peuvent être considérés comme des filtres qui ignorent leur entrée et produisent toujours la même valeur.

Une fois installé, jq est appelé de la ligne de commande : jq [options] 'filtre' fichier, le filtre étant entouré d'apostrophes simples pour éviter qu'il soit interprété par le shell avant d'être passé à jq.

Un filtre est appliqué à un flot de données JSON. jq analyse ce flot comme une séquence de valeurs JSON, chaque valeur étant séparée d’un espace. Chaque valeur est ensuite validée, puis transmise une à une. Le filtre renvoie ses résultats sur stdout, sous forme d’une séquence de valeurs JSON séparées par un retour chariot. Par défaut, la sortie JSON est indentée pour en faire ressortir la structure (pretty-print). Cette indentation n'est pas appliquée si l'option -c ou --compact-output est spécifiée lors de l'appel de jq.

Rappelons qu'outre les valeurs primitives (nombre, chaîne de caractères, booléen, null), JSON fournit deux structures de données:

Voici ma sélection personnelle de fonctions parmi la centaine décrites dans le manuel.

Filtres

Regroupements

Opérations

Tests

Traitement de chaînes

Exemples d'utilisation

Conseil: essayez ces exemples avec jqTerm ou jqplay qui permettent de les faire exécuter depuis une page web et d'afficher les résultats immédiatement.

Fichier .json [source]

La structure JSON suivante représente un extrait d'un dictionnaire anglais dont les clés sont des mots. À chaque mot est associé un objet qui décrit des informations selon sa catégorie (A: adjectif, N: nom ou V: verbe). À chaque catégorie est associée une table de flexions (tab) et, pour certains, si le mot est courant (basic). Un nom peut être comptable (yes), non-comptable (no) ou les deux (both) .

Opérations [source]

Fichier .jsonl [source]

Chaque ligne d'un fichier JSON Lines est un objet JSON décrivant un mot.

Note: Ce fichier aurait pu être créé à partir du précédent avec l'expression to_entries[] | {word:.key}+.value.

Comme il y a plusieurs objets JSON dans le même fichier, l'expression jq est appliquée à chacun et chaque résultat est concaténé sur la sortie. Un objet JSON peut chevaucher une ou plusieurs lignes pourvu que sa structure soit correcte.

Opérations [source]

Note: Pour les curieux: avec l'option -s , l'expression

appliquée sur le fichier .jsonl recrée la structure JSON de la section précédente en partant d'un objet vide de la façon suivante: pour chaque élément du tableau, on fusionne un objet ayant pour clé la valeur de la clé word et, pour valeur, toutes les propriétés de l'élément sauf le champ word.

Liens intéressants