Aide-mémoire jq

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

[English version of this document]

jq est un outil en 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.

La documentation officielle contient un tutoriel présentant quelques exemples ainsi qu’un manuel qui énumère toutes les fonctions illustrées par un court exemple. Elle ne décrit cependant pas comment enchaîner ces fonctions pour effectuer des tâches intéressantes. La syntaxe des expressions jq peut sembler déroutante, car elle s’appuie sur la composition de filtres plutôt que sur une notation fonctionnelle plus familière. jq est un véritable langage de programmation doté de structures de contrôle, de variables, de fonctions et même de modules. Comme toutes mes applications se sont limitées à la composition d'une seule expression, 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 sur le web, dont celui-ci qui est excellent, mais maintenant truffé de publicités. Cependant, ils n'insistent pas sur les éléments que je trouve les plus utiles dans les cas d'utilisation que j'ai rencontrés, c’est-à-dire l'extraction et la transformation de données JSON dans des fichiers.

Ce document me servira donc d'aide-mémoire même si, après l'avoir rédigé, je suis moins susceptible d'en avoir besoin ; toutefois, j'espère qu'il sera utile à d'autres personnes.

Concepts de base

Une expression jq est un filtre qui transforme une entrée en une sortie. 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 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é sur un flot de données JSON. jq analyse ce flot comme une séquence de valeurs JSON séparées par des espaces qui sont validées et données en entrée au filtre une à une. La ou les sorties du filtre sont envoyées sur stdout comme une séquence de valeurs JSON séparées par un newline. Par défaut, la valeur JSON est affichée avec une indentation pour faire ressortir la structure du JSON (pretty-print). Cette indentation n'est pas appliquée si l'option -c est spécifiée.

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

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

Filtres de base

Regroupements

Filtres

Tests

Traitement de chaînes

Exemples pratiques

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

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,. 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

Fichier .jsonl

Chaque ligne d'un fichier JSON Lines est un objet json décrivant un mot. Ce fichier aurait pu être créé à partir du précédent avec l'expression to_entries[] | {word:.key}+.value

Opérations

Il est possible de traiter les lignes d'un fichier .jsonl comme un tableau de structures en spécifiant l'option --slurp (-s).

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

recrée la structure JSON de la section précédente en partant d'un objet vide; 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