Wie konvertiert man eingebetteten (zitierten) JSON-String in JSON

22

Ich kenne "jq" zum Parsen von json.

Ich arbeite mit einem Dienst, der eine JSON-Antwort erzeugt, wobei eine der Eigenschaften selbst eine JSON-Zeichenfolge ist. Wie konvertiere ich diesen zitierten Wert in eine gültige JSON-Zeichenfolge, damit ich ihn dann mit JQ verarbeiten kann?

Wenn ich zum Beispiel nur den einfachen, hübsch gedruckten json aus "jq." Ansehe, ist hier ein kurzer Auszug der Ausgabe:

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

Ich kann jq verwenden, um den Wert dieser Eigenschaft abzurufen, aber ich muss den in Anführungszeichen gesetzten String in einen gültigen json konvertieren, indem ich ihn "ausbaue".

Ich nehme an, ich könnte es in sed umleiten, die öffnenden und endenden doppelten Anführungszeichen entfernen und alle Backslashes (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'") entfernen . Das scheint zu funktionieren, aber das scheint nicht die robusteste Lösung zu sein.

Update :

Um ein bisschen klarer zu sein, was ich tue, hier ein paar Beispiele, die zeigen, was ich versucht habe:

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

Update :

Hier ist ein völlig eigenständiges Beispiel:

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

Update :

Wenn ich versucht habe, diese letzte Ausgabe mit einem echten jq-Ausdruck zu verarbeiten, geschieht Folgendes:

% 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)
David M. Karr
quelle
Wenn Sie verwenden jq, um nur den Wert der Zeichenfolge-Eigenschaft abzurufen, wird er dann ohne Flucht zurückgegeben? Wenn ja, leiten Sie das einfach in ein frisches jq.
DopeGhoti
Nein, es gibt es nicht ohne Flucht zurück. Das ist der Punkt.
David M. Karr
Wie wäre es echo $(jq statement here)?
DopeGhoti
Nein, keine Veränderung.
David M. Karr
@ DavidM.Karr, ok, wenn möglich - erweitern Sie Ihre Eingabe mit der eigentlichen entscheidenden Zeichenfolge und dem Endergebnis
RomanPerekhrest

Antworten:

20

Dafür gibt es eine rawFlagge

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

Ausgabe

{"date":"2018-01-08"}
cricket_007
quelle
Der Unterschied besteht darin, dass Sie mit der Antwort von Roman garantiert eine gültige JSON-Ausgabe oder Fehlermeldungen erhalten, wenn es sich um eine ungültige JSON handelt.
Kusalananda
Gültiger Punkt, aber wenn dies in der Automatisierung verwendet wird, denke ich, dass es ungewöhnlich wäre, plötzlich keine gültige JSON-Ausgabe zu haben. Die bequemste Form wird fast immer vollkommen in Ordnung sein. Es ist jedoch immer noch gut, genauere Methoden zu kennen.
David M. Karr
@ DavidM.Karr "ungewöhnlich, plötzlich keine gültige json-Ausgabe zu haben" HA! Riiiight. Fehlerbehandlung in der Automatisierung? Fehler werden niemals passieren! Warum die Mühe!
Bruno Bronosky
jqFür die weitere JSON-Verarbeitung müssen Sie eine Pipeline an eine andere senden, wohingegen Sie mit dem Ansatz von Roman denselben jqAusdruck fortsetzen können.
Raman
1
@ cricket_007: habe es mit jq 1.5 versucht und bestätigt, dass es nicht funktioniert: jq -rc '.stuff.date'produziert jq: error (at <stdin>:0): Cannot index string with string "date". Allerdings: .stuff | fromjson | .datefunktioniert gut.
Raman
26

Mit jq's fromjsonFunktion:

Beispielinhalt stuff.json:

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

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

Die Ausgabe:

{"date":"2018-01-08"}
RomanPerekhrest
quelle
Das scheint unnötig. Vorausgesetzt, alternative Antwort
cricket_007