Salut à toi, Nal,
Connais tu jq
?
C'est un outil en ligne de commande bien pratique quand on a des données en JSON et qu'on veut en extraire quelques infos. On lui passe un fichier JSON, une expression bien sentie dans un langage spécifique et concis, et le tour est joué.
Alors, je sais pas pour toi, Nal, mais je galère quand même pas mal chaque fois pour réussir à écrire l'expression qui va bien, car jq
a son langage à lui, et il n'est pas des plus simples. Je trouve que ça devient assez compliqué dès qu'il s'agit de faire une boucle qui fait un peu plus que retourner un champ d'un dictionnaire.
Ça serait quand même plus pratique si la syntaxe était celle d'un langage que je maitrise déjà, par exemple Python.
Bon, à ce stade là de mon approche pas très discrète, tu dois te douter que je vais tenter de te vendre ma came. Alors allons-y : j'ai écrit pjy
, un outil comme jq
, mais qui utilise la syntaxe de Python. Si tu connais Python, tu sais (presque) déjà utiliser pjy
.
pjy 'data["toto"] + 1' fichier.json
Comme pour jq
, on passe d'abord l'expression à évaluer (en Python cette fois), et le fichier JSON. data
représente le fichier JSON. Ici, le fichier JSON était un dictionnaire avec une clef toto
, et j'affiche la valeur associée à cette clef, plus un. Simple.
Malgré sa syntaxe facétieuse, il faut bien avouer que la notation de jq
x.y
au lieu de x["y"]
est pratique. Je l'ai donc emprunté (et ajouté un alias "d" pour "data") :
pjy 'd.toto + 1' fichier.json
À ce moment là, j'étais déjà content du résultat, débarrassé de jq
, je pouvais enfin écrire une double boucle sans m'arracher les cheveux :
[[s[:i] for i in range(len(s))] for s in d.chaines]
Mais je me suis dit que jq
avait quelques petits trucs sympas, que je pouvais également emprunter, de manière optionnelle bien entendue, pour qu'on puisse toujours revenir à une syntaxe Python, standard et lisible, qui est la raison d'être de pjy
.
J'ai donc emprunté à jq
la barre verticale pour réaliser la fonction map
, on peut ainsi remplacer :
map(lambda x: x + 1, data["nombres"])
Par :
data["nombres"] | lambda x: x + 1
Si tu as tout suivi, tu noteras que l'on peut également écrire :
d.nombres | lambda x: x + 1
J'avais repéré depuis pas mal de temps le paquet placeholder
, qui permet d'écrire des lambdas basiques de manière assez concise. Je l'ai ré-implémenté et rajouté la variable _
qui une fonction spéciale, au début la fonction identité, mais qui absorbe toutes les opérations pour les ré-appliquer plus tard. En reprenant l'exemple précédent, ça donne :
d.nombres | _ + 1
Il y a quelques petites fonctionnalités en plus (comme plusieurs fichiers en entrée), que tu pourras découvrir.
Si tu es curieux ou convaincu, je t'invite à tester : https://pypi.python.org/pypi/pjy
pip3 install pjy
C'est du Python 3, pas de Python 2, et pas de dépendances externes (pygments
est optionnel, pour la coloration). C'est sous licence WTFPL.
À noter ce paquet qu'il peut être intéressant d'utiliser dans pjy
: http://0101.github.io/pipetools/doc/
Que penses-tu de tout ça, Nal ?
# jq
Posté par Benoît Sibaud (site web personnel) . Évalué à 9.
Pour info, S. Bortzmeyer a écrit un billet sympa sur jq http://www.bortzmeyer.org/jq.html . Pour le reste, c'est le classique problème de la poule et de l'oeuf, jq est disponible dans (quasi?) toutes les distributions même anciennes, il est déjà bien implanté, etc. D'où l'intérêt de montrer en quoi pjy fait mieux/plus. Par ailleurs pjy vise probablement plus dans un premier temps les développeurs python qui utilisent de toute façon déjà pip régulièrement pour ramener des paquets divers et variés.
[^] # Re: jq
Posté par Faya . Évalué à 3.
Et bien j'avais raté ce post de Bortzmeyer ! Merci du lien, c'est très intéressant.
( Voilà encore une fois l'utilité d'une section "Brèves" où on pourrait poster des bookmarks… )
[^] # Re: jq
Posté par BAud (site web personnel) . Évalué à 3.
oui, il y a une entrée : https://linuxfr.org/suivi/une-categorie-bookmark peu commentée :/
pour créer une section de dépêches : proposer un nom, fournir une image en SVG préférentiellement, faire l'entrée de suivi… profit !
# D'autres alternatives
Posté par Bruno Michel (site web personnel) . Évalué à 8.
À noter qu'il existe d'autres alternatives pour manipuler du JSON :
[^] # Re: D'autres alternatives
Posté par ckyl . Évalué à 4.
En dehors de sa syntaxe parfois difficile à mémoriser pour les expressions compliquées et de sa gestion des
number
, le plus gros reproche que j'avais à faire àjq
ce sont ses performances. Il plafonne à quelques MB/s.As tu une idée si les autres outils sont un peu moins limités de ce côté là ?
[^] # Re: D'autres alternatives
Posté par Bruno Michel (site web personnel) . Évalué à 4.
Je n'en ai pas la moindre idée, je ne travaille généralement qu'avec des petits documents (moins d'un Mo).
[^] # Re: D'autres alternatives
Posté par BFG . Évalué à 2.
Ils ont globalement tous une syntaxe particulière spécifique à apprendre et qui atteindra probablement vite ses limites face à des cas un tant soi peu complexes.
# Dans le même registre jsawk
Posté par Thomas Douillard . Évalué à 5.
J’en ai utilisé un autre dans le genre dans le passé : https://github.com/micha/jsawk . Comme awk balance du texte en sortie, ça peut balancer du json en sortie. On peut extraire des données pour les sortir formatées en texte comme on veut, et le langage n’est pas du awk mais du js à la place.
[^] # Re: Dans le même registre jsawk
Posté par BFG . Évalué à 3.
Dans le principe, je préfère ça à
jq
, car cela réutilise une syntaxe déjà familière, qui plus est éprouvée, plutôt que réinventer une nouvelle fois la roue. Mais question de goût personnel, je préfère le Python au javascript.# json_pp
Posté par Yves (site web personnel) . Évalué à 2.
Sans rien installer, json_pp est en général déjà disponible : il vient avec perl 5. Entre autres choses, il permet de « jolifier » un flux JSON.
[^] # Re: json_pp
Posté par BFG . Évalué à 2.
S'il ne s'agit que d'indenter,
json_pp
fait l'affaire. Je parlais d'exécuter des expressions sur le JSON, par exemple si le JSON consiste en une liste de dictionnaire, dont seulement un champ nous intéresse, il faut fairepjy '[sub.mon_champ for sub in data]' fichier.json
.Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.