Comment convertir une chaîne json incorporée (citée) en json


22

Je connais "jq" pour analyser json.

Je travaille avec un service qui produit une réponse json où l'une des propriétés est elle-même une chaîne json. Comment convertir cette valeur entre guillemets en une chaîne json valide afin de pouvoir ensuite la traiter avec jq?

Par exemple, si je regarde simplement le json joliment imprimé de "jq.", Voici un court extrait de la sortie:

"someJsonString": "{\"date\":\"2018-01-08\", ...

Je peux utiliser jq pour obtenir la valeur de cette propriété, mais je dois convertir la chaîne entre guillemets en json valide en la "décompressant".

Je suppose que je pourrais le diriger vers sed, en supprimant les guillemets doubles d'ouverture et de fin et en supprimant toutes les barres obliques inverses (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'"). Cela semble fonctionner, mais cela ne semble pas être la solution la plus robuste.

Mise à jour :

Juste pour être un peu plus clair sur ce que je fais, voici quelques exemples élidés qui montrent ce que j'ai essayé:

% curl -s -q -L 'http://.../1524.json' | jq '.results[0].someJsonString' | jq .
"{\"date\":\"2018-01-08\",...
% echo $(curl -s -q -L 'http:/.../1524.json' | jq '.results[0].someJsonString') | jq .
"{\"date\":\"2018-01-08\",...

Mise à jour :

Voici un exemple complètement autonome:

% cat stuff.json | jq .
{
  "stuff": "{\"date\":\"2018-01-08\"}"
}
% cat stuff.json | jq '.stuff'
"{\"date\":\"2018-01-08\"}"
% cat stuff.json | jq '.stuff' | jq .
"{\"date\":\"2018-01-08\"}"

Mise à jour :

Si j'ai essayé de traiter cette dernière sortie avec une véritable expression jq, cela fait quelque chose comme ceci:

% cat stuff.json | jq '.stuff' | jq '.date'
assertion "cb == jq_util_input_next_input_cb" failed: file "/usr/src/ports/jq/jq-1.5-3.x86_64/src/jq-1.5/util.c", line 371, function: jq_util_input_get_position
Aborted (core dumped)

Si vous utilisez jqpour obtenir uniquement la valeur de la propriété de chaîne, la renvoie-t-elle sans échappement? Si c'est le cas, il vous suffit de le canaliser dans un nouveau jq.
DopeGhoti

Non, il ne le rend pas sans échappatoire. C'est le but.
David M. Karr

Et alors echo $(jq statement here)?
DopeGhoti

Non, pas de changement.
David M. Karr

@ DavidM.Karr, ok, si possible - étendez votre entrée avec la chaîne cruciale réelle et le résultat final
RomanPerekhrest

Réponses:


20

Il y a un rawdrapeau pour ça

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

Sortie

{"date":"2018-01-08"}

La différence est qu'avec la réponse de Roman, vous êtes assuré d'obtenir une sortie JSON valide ou des messages d'erreur si ce n'est pas du JSON valide.
Kusalananda

Point valide, mais si cela est utilisé dans l'automatisation, je pense qu'il serait inhabituel de ne pas avoir soudainement une sortie json valide. La forme la plus pratique sera parfaitement fine presque tout le temps. Cependant, il est toujours bon de connaître des méthodes plus précises.
David M. Karr

@ DavidM.Karr "inhabituel de ne pas avoir soudainement une sortie json valide" HA! Riiiight. Gestion des erreurs dans l'automatisation? Les erreurs ne se produiront jamais ! Pourquoi s'embêter!
Bruno Bronosky

Cela nécessite un raccordement à un autre jqpour un traitement JSON ultérieur, tandis qu'avec l'approche de Roman, vous pouvez continuer la même jqexpression.
Raman

1
@ cricket_007: l'a essayé avec jq 1.5, et a confirmé qu'il ne fonctionne pas: jq -rc '.stuff.date'produit jq: error (at <stdin>:0): Cannot index string with string "date". Cependant: .stuff | fromjson | .datefonctionne très bien.
Raman

26

Avec jqla fromjsonfonction:

Exemples de stuff.jsoncontenu:

{
  "stuff": "{\"date\":\"2018-01-08\"}"
}

jq -c '.stuff | fromjson' stuff.json

Le résultat:

{"date":"2018-01-08"}

Cela semble inutile. Réponse alternative fournie
cricket_007
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.