extraction de json dans json avec jq [duplicate]

Nov 03 2020

Je me retrouve souvent à vouloir analyser json avec la jqcommande, mais l'une des valeurs à l'intérieur du json est une chaîne échappée de json.

par exemple, si je génère des données avec python comme ceci:

import json
inner = {'a': 'b'}
outer = {'x': json.dumps(inner)}
json.dumps(outer)

Je reçois:

{"x": "{\"a\": \"b\"}"}

Comment "b"utiliser la jqcommande?

$ echo '{"x": "{\"a\": \"b\"}"}' | jq .x
"{\"a\": \"b\"}"

Ok, c'est la première étape. Mais le résultat n'est pas un dictionnaire json. C'est une chaîne qui doit être échappée et analysée dans json.

jq .x.a jette une erreur: jq: error (at <stdin>:1): Cannot index string with string "a"

Y a-t-il un argument auquel je peux ajouter jqpour enchaîner deux jqétapes? Ou y a-t-il une autre commande que je peux utiliser à la place?

par exemple

echo '{"x": "{\"a\": \"b\"}"}' | jq .x | jq --some-argument .a

ou alors

echo '{"x": "{\"a\": \"b\"}"}' | jq .x | something-else | jq .a

Réponses

1 CasperDijkstra Nov 03 2020 at 07:15

Ce qui suit fait l'affaire:

echo '{"x": "{\"a\": \"b\"}"}' | jq -r .x | jq .a

Ici, l' -rétape garantit que la sortie est constituée de chaînes brutes et non de textes JSON. Par conséquent:

"{\"a\": \"b\"}" -> {"a": "b"},

où cette "chaîne brute" peut ensuite être prise comme entrée JSON pour jq .a, renvoyer "b"(ou blorsqu'elle est utilisée avec un -rindicateur).

EDIT : Appeler jqdeux fois n'est pas idéal (merci @peak), la commande précédente peut être combinée dans ce oneliner

| jq -r '.x|fromjson.a'