วิธีการแปลงสตริง json แบบฝัง (ที่ยกมา) เป็น json


22

ฉันคุ้นเคยกับ "jq" สำหรับการแยกวิเคราะห์ json

ฉันทำงานกับหนึ่งบริการที่สร้างการตอบสนอง json โดยที่คุณสมบัติอย่างใดอย่างหนึ่งคือสตริง json ฉันจะแปลงค่าที่ยกมาเป็นสตริง json ที่ถูกต้องเพื่อให้ฉันสามารถประมวลผลด้วย jq ได้อย่างไร

ตัวอย่างเช่นหากฉันเพิ่งดู json ที่พิมพ์สวยแบบธรรมดาจาก "jq." นี่เป็นข้อความที่ตัดตอนมาสั้น ๆ ของผลลัพธ์:

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

ฉันสามารถใช้ jq เพื่อรับค่าของคุณสมบัตินั้น แต่ฉันต้องแปลงสตริงที่ยกมาเพื่อ json ที่ถูกต้องโดย "unescaping" มัน

ฉันคิดว่าฉันสามารถแปะไปที่ sed ลบการเปิดและสิ้นสุดเครื่องหมายคำพูดคู่และลบเครื่องหมายแบ็กสแลชทั้งหมด (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'") ดูเหมือนว่าจะใช้งานได้ แต่ไม่ได้ดูเหมือนโซลูชันที่แข็งแกร่งที่สุด

อัปเดต :

เพื่อให้ชัดเจนขึ้นเกี่ยวกับสิ่งที่ฉันทำนี่เป็นตัวอย่างสองสามตัวอย่างที่แสดงสิ่งที่ฉันได้ลอง:

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

อัปเดต :

นี่เป็นตัวอย่างแบบสแตนด์อโลนอย่างสมบูรณ์:

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

อัปเดต :

ถ้าฉันพยายามประมวลผลเอาต์พุตสุดท้ายด้วยนิพจน์ jq จริงมันทำอะไรเช่นนี้:

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

ถ้าคุณใช้jqจะได้รับเพียงแค่มูลค่าของทรัพย์สินสตริงไม่ก็กลับไปใช้ Escape? jqถ้าเป็นเช่นนั้นเพียงท่อที่เป็นสด
DopeGhoti

ไม่มันไม่ส่งคืนโดยไม่ใช้ค่า Escape นั่นคือประเด็น
David M. Karr

แล้วไงecho $(jq statement here)ล่ะ
DopeGhoti

ไม่ไม่มีการเปลี่ยนแปลง
David M. Karr

@ DavidM.Karr โอเคถ้าเป็นไปได้ - ขยายความคิดเห็นของคุณด้วยสตริงสำคัญที่แท้จริงและผลลัพธ์สุดท้าย
RomanPerekhrest

คำตอบ:


20

มีrawธงสำหรับสิ่งนี้

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

เอาท์พุต

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

ข้อแตกต่างคือด้วยคำตอบของโรมันคุณจะรับประกันว่าจะได้รับเอาต์พุต JSON ที่ถูกต้องหรือข้อความแสดงข้อผิดพลาดหากไม่ใช่ JSON ที่ถูกต้อง
Kusalananda

จุดที่ถูกต้อง แต่ถ้าใช้ในระบบอัตโนมัติฉันคิดว่ามันผิดปกติถ้าจู่ๆไม่มีเอาต์พุต json ที่ถูกต้อง รูปแบบที่สะดวกที่สุดจะถูกปรับอย่างสมบูรณ์แบบเกือบตลอดเวลา อย่างไรก็ตามยังคงเป็นเรื่องดีที่จะทราบวิธีการที่แม่นยำยิ่งขึ้น
David M. Karr

@ DavidM.Karr "ผิดปกติไม่ได้ json output ที่ถูกต้อง" HA! Riiiight เกิดข้อผิดพลาดในการจัดการอัตโนมัติ? ข้อผิดพลาดจะไม่เกิดขึ้น! ทำไมต้องรำคาญ!
Bruno Bronosky

สิ่งนี้ต้องการการไพพ์ไปยังอีกอันjqเพื่อการประมวลผล JSON เพิ่มเติมในขณะที่ด้วยวิธีการของโรมันคุณสามารถดำเนินการต่อการjqแสดงออกที่เหมือนกัน
Raman

1
@ cricket_007: พยายามกับ JQ 1.5 และยืนยันว่าไม่ได้ทำงาน: ผลิตjq -rc '.stuff.date' jq: error (at <stdin>:0): Cannot index string with string "date"อย่างไรก็ตาม: .stuff | fromjson | .dateทำงานได้ดี
Raman

26

ด้วยjqของfromjsonฟังก์ชั่น:

stuff.jsonเนื้อหาตัวอย่าง:

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

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

ผลลัพธ์:

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

ดูเหมือนว่าไม่จำเป็น ให้คำตอบทางเลือก
cricket_007
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.