Come convertire una stringa json incorporata (quotata) in json


22

Conosco "jq" per analizzare json.

Lavoro con un servizio che produce una risposta json in cui una delle proprietà è essa stessa una stringa json. Come posso convertire quel valore tra virgolette in una stringa json valida in modo da poterlo elaborare con jq?

Ad esempio, se vedo solo il semplice json piuttosto stampato da "jq.", Ecco un breve estratto dell'output:

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

Posso usare jq per ottenere il valore di quella proprietà, ma ho bisogno di convertire la stringa tra virgolette in json valido "annullando l'escaping" di esso.

Suppongo di poterlo convogliare in sed, rimuovendo l'apertura e la fine delle doppie virgolette e rimuovendo tutte le barre rovesciate (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'"). Sembra funzionare, ma non sembra la soluzione più solida.

Aggiornamento :

Solo per essere un po 'più chiaro su quello che sto facendo, ecco un paio di esempi elisi che mostrano ciò che ho provato:

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

Aggiornamento :

Ecco un esempio completamente autonomo:

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

Aggiornamento :

Se provassi a elaborare l'ultimo output con una vera espressione jq, fa qualcosa del genere:

% 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)

Se si utilizza jqper ottenere solo il valore della proprietà stringa, lo restituisce senza caratteri di escape? Se è così, basta inserirlo in un nuovo jq.
DopeGhoti

No, non lo restituisce senza caratteri di escape. Questo è il punto.
David M. Karr

Che ne dici echo $(jq statement here)?
DopeGhoti,

No, nessun cambiamento.
David M. Karr,

@ DavidM.Karr, ok, se possibile - estendi l'input con la stringa cruciale effettiva e il risultato finale
RomanPerekhrest

Risposte:


20

C'è una rawbandiera per questo

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

Produzione

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

La differenza è che con la risposta di Roman, sei sicuro di ottenere un output JSON valido o messaggi di errore se non è JSON valido.
Kusalananda

Punto valido, ma se questo viene utilizzato nell'automazione, penso che sarebbe insolito non avere improvvisamente un output json valido. La forma più conveniente andrà perfettamente bene quasi sempre. È comunque utile conoscere metodi più precisi, tuttavia.
David M. Karr,

@ DavidM.Karr "insolito non avere improvvisamente un output json valido" HA! Riiiight. Gestione degli errori nell'automazione? Gli errori non accadranno mai ! Perché preoccuparsi!
Bruno Bronosky,

Ciò richiede il piping a un altro jqper ulteriore elaborazione JSON, mentre con l'approccio di Roman è possibile continuare la stessa jqespressione.
Raman

1
@ cricket_007: provato con jq 1.5 e confermato che non funziona: jq -rc '.stuff.date'produce jq: error (at <stdin>:0): Cannot index string with string "date". Tuttavia: .stuff | fromjson | .datefunziona bene.
Raman

26

Con jqla fromjsonfunzione:

stuff.jsonContenuto del campione :

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

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

L'output:

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

Questo non sembra necessario. Risposta alternativa fornita
cricket_007,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.