Cómo convertir una cadena json incrustada (citada) a json


22

Estoy familiarizado con "jq" para analizar json.

Trabajo con un servicio que produce una respuesta json donde una de las propiedades es en sí misma una cadena json. ¿Cómo convierto ese valor citado en una cadena json válida para que luego pueda procesarlo con jq?

Por ejemplo, si acabo de ver el json bastante impreso de "jq.", Aquí hay un breve extracto de la salida:

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

Puedo usar jq para obtener el valor de esa propiedad, pero necesito convertir la cadena entre comillas a json válida "quitándola".

Supongo que podría canalizarlo a sed, eliminando las comillas dobles de apertura y finalización, y eliminando todas las barras invertidas (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'"). Eso parece funcionar, pero esa no parece ser la solución más sólida.

Actualización :

Solo para ser un poco más claro sobre lo que estoy haciendo, aquí hay un par de muestras eliminadas que muestran lo que he intentado:

% 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\",...

Actualización :

Aquí hay un ejemplo completamente independiente:

% 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\"}"

Actualización :

Si intenté procesar esa última salida con una expresión jq real, hace algo como esto:

% 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 usa jqpara obtener solo el valor de la propiedad de cadena, ¿la devuelve sin escape? Si es así, simplemente póngalo en una nueva jq.
DopeGhoti

No, no lo devuelve sin escapar. Ese es el punto.
David M. Karr

¿Qué tal echo $(jq statement here)?
DopeGhoti

No, no hay cambio.
David M. Karr

@ DavidM.Karr, ok, si es posible - amplíe su entrada con la cadena crucial real y el resultado final
RomanPerekhrest

Respuestas:


20

Hay una rawbandera para esto

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

Salida

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

La diferencia es que con la respuesta de Roman, se garantiza que obtendrá una salida JSON válida o mensajes de error si no es una JSON válida.
Kusalananda

Punto válido, pero si esto se usa en automatización, creo que sería inusual no tener una salida json válida. La forma más conveniente estará perfectamente bien casi todo el tiempo. Sin embargo, todavía es bueno saber acerca de métodos más precisos.
David M. Karr

@ DavidM.Karr "inusual que de repente no tenga salida json válida" ¡HA! Riiiight. ¿Manejo de errores en automatización? ¡Los errores nunca sucederán! ¡Por qué molestarse!
Bruno Bronosky

Esto requiere canalizar a otro jqpara un mayor procesamiento JSON, mientras que con el enfoque de Roman puede continuar la misma jqexpresión.
Raman

1
@ cricket_007: lo probé con jq 1.5 y confirmó que no funciona: jq -rc '.stuff.date'produce jq: error (at <stdin>:0): Cannot index string with string "date". Sin embargo: .stuff | fromjson | .datefunciona bien.
Raman

26

Con jqla fromjsonfunción de:

stuff.jsonContenido de muestra :

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

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

La salida:

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

Esto parece poco práctico. Respuesta alternativa proporcionada
cricket_007
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.