Cara mengonversi string json yang tertanam (dikutip) menjadi json


22

Saya kenal dengan "jq" untuk parsing json.

Saya bekerja dengan satu layanan yang menghasilkan respons json di mana salah satu properti itu sendiri adalah string json. Bagaimana cara mengonversi nilai yang dikutip itu menjadi string json yang valid sehingga saya dapat memprosesnya dengan jq?

Sebagai contoh, jika saya hanya melihat json yang cukup dicetak dari "jq.", Berikut adalah kutipan singkat dari output:

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

Saya bisa menggunakan jq untuk mendapatkan nilai dari properti itu, tapi saya perlu mengubah string yang dikutip menjadi json yang valid dengan "unescaping" itu.

Saya kira saya bisa memasukkannya ke dalam sed, menghapus tanda kutip ganda yang membuka dan mengakhiri, dan menghapus semua garis miring terbalik (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'"). Tampaknya berhasil, tetapi itu sepertinya bukan solusi yang paling kuat.

Perbarui :

Agar sedikit lebih jelas tentang apa yang saya lakukan, berikut adalah beberapa contoh elided yang menunjukkan apa yang saya coba:

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

Perbarui :

Inilah contoh yang sepenuhnya mandiri:

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

Perbarui :

Jika saya mencoba untuk memproses output terakhir dengan ekspresi jq nyata, ia melakukan sesuatu seperti ini:

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

Jika Anda menggunakan hanyajq untuk mendapatkan nilai dari properti string, apakah mengembalikannya tidak terhapus? Jika demikian, hanya pipa yang menjadi segar . jq
DopeGhoti

Tidak, itu tidak mengembalikannya tanpa hambatan. Itulah intinya.
David M. Karr

Bagaimana dengan echo $(jq statement here)?
DopeGhoti

Tidak, tidak ada perubahan.
David M. Karr

@ DavidM.Karr, ok, Jika mungkin - perpanjang input Anda dengan string krusial aktual dan hasil akhir
RomanPerekhrest

Jawaban:


20

Ada rawbendera untuk ini

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

Keluaran

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

Perbedaannya adalah bahwa dengan jawaban Roman, Anda dijamin mendapatkan output JSON yang valid, atau pesan kesalahan jika bukan JSON yang valid.
Kusalananda

Poin yang valid, tetapi jika ini sedang digunakan dalam otomatisasi, saya pikir itu tidak biasa untuk tiba-tiba tidak memiliki output json yang valid. Bentuk yang paling nyaman akan baik-baik saja hampir sepanjang waktu. Namun, masih baik untuk mengetahui tentang metode yang lebih tepat.
David M. Karr

@ DavidM.Karr "tidak biasa tiba-tiba tidak memiliki output json yang valid" HA! Riiiight. Kesalahan penanganan dalam otomatisasi? Kesalahan tidak akan pernah terjadi! Mengapa mengganggu!
Bruno Bronosky

Ini membutuhkan pemipaan ke yang lain jquntuk pemrosesan JSON lebih lanjut, sedangkan dengan pendekatan Roman Anda dapat melanjutkan jqekspresi yang sama .
Raman

1
@ cricket_007: mencobanya dengan jq 1.5, dan mengonfirmasi itu tidak berfungsi: jq -rc '.stuff.date'menghasilkan jq: error (at <stdin>:0): Cannot index string with string "date". Namun: .stuff | fromjson | .dateberfungsi dengan baik.
Raman

26

Dengan jq's fromjsonfungsi:

stuff.jsonIsi sampel :

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

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

Hasil:

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

Ini sepertinya tidak penting. Memberikan jawaban alternatif
cricket_007
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.