Cách chuyển đổi chuỗi json nhúng (trích dẫn) sang json


22

Tôi quen thuộc với "jq" để phân tích cú pháp json.

Tôi làm việc với một dịch vụ tạo ra phản hồi json trong đó một trong các thuộc tính chính là chuỗi json. Làm cách nào để chuyển đổi giá trị được trích dẫn đó thành chuỗi json hợp lệ để sau đó tôi có thể xử lý nó với jq?

Chẳng hạn, nếu tôi chỉ xem json được in khá đơn giản từ "jq.", Đây là một đoạn trích ngắn của đầu ra:

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

Tôi có thể sử dụng jq để lấy giá trị của thuộc tính đó, nhưng tôi cần chuyển đổi chuỗi được trích dẫn thành json hợp lệ bằng cách "hủy bỏ" nó.

Tôi cho rằng tôi có thể chuyển nó thành sed, loại bỏ dấu ngoặc kép mở và kết thúc và xóa tất cả dấu gạch chéo ngược (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'"). Điều đó có vẻ hiệu quả, nhưng đó dường như không phải là giải pháp mạnh mẽ nhất.

Cập nhật :

Nói rõ hơn một chút về những gì tôi đang làm, đây là một vài mẫu thử cho thấy những gì tôi đã thử:

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

Cập nhật :

Đây là một ví dụ hoàn toàn độc lập:

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

Cập nhật :

Nếu tôi đã cố xử lý đầu ra cuối cùng đó bằng biểu thức jq thực, thì nó sẽ hoạt động như sau:

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

Nếu bạn sử dụng jqđể chỉ lấy giá trị của thuộc tính chuỗi, nó có trả về nó không bị hủy không? Nếu vậy, chỉ cần ống mà vào một tươi jq.
DopeGhoti

Không, nó không trả lại nó không được giải thoát. Đó là điểm.
David M. Karr

Thế còn echo $(jq statement here)?
DopeGhoti

Không, không thay đổi.
David M. Karr

@ DavidM.Karr, ok, Nếu có thể - hãy mở rộng đầu vào của bạn bằng chuỗi quan trọng thực tế và kết quả cuối cùng
RomanPerekhrest

Câu trả lời:


20

Có một rawlá cờ cho điều này

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

Đầu ra

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

Sự khác biệt là với câu trả lời của Roman, bạn được đảm bảo nhận được đầu ra JSON hợp lệ hoặc thông báo lỗi nếu đó không phải là JSON hợp lệ.
Kusalananda

Điểm hợp lệ, nhưng nếu điều này đang được sử dụng trong tự động hóa, tôi nghĩ sẽ bất thường khi đột nhiên không có đầu ra json hợp lệ. Các hình thức thuận tiện nhất sẽ hoàn toàn tốt đẹp hầu như mọi lúc. Tuy nhiên, vẫn còn tốt để biết về các phương pháp chính xác hơn.
David M. Karr

@ DavidM.Karr "bất thường khi đột nhiên không có đầu ra json hợp lệ" HA! Riiiight. Xử lý lỗi trong tự động hóa? Lỗi sẽ không bao giờ xảy ra! Quan tâm làm gì!
Bruno Bronosky

Điều này đòi hỏi phải chuyển sang hệ thống khác jqđể xử lý JSON hơn nữa, trong khi với cách tiếp cận của Roman, bạn có thể tiếp tục jqbiểu thức tương tự .
Raman

1
@ cricket_007: đã thử nó với jq 1.5 và xác nhận rằng nó không hoạt động: jq -rc '.stuff.date'sản xuất jq: error (at <stdin>:0): Cannot index string with string "date". Tuy nhiên: .stuff | fromjson | .datehoạt động tốt.
Raman

26

Với jq's fromjsonchức năng:

stuff.jsonNội dung mẫu :

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

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

Đầu ra:

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

Điều này có vẻ không thông minh. Cung cấp câu trả lời thay thế
cricket_007
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.