Użyj jq, aby przeanalizować ciąg JSON

87

Próbuję jqprzeanalizować strukturę JSON, taką jak:

{
  "a" : 1,
  "b" : 2,
  "c" : "{\"id\":\"9ee ...\",\"parent\":\"abc...\"}\n"
}

Oznacza to, że element w formacie JSON jest ciągiem znaków ze zmienionym kodem JSON.

Więc mam coś w stylu $ jq [.c] myFile.json | jq [.id]

Ale to się psuje jq: error: Cannot index string with string

Dzieje się tak, ponieważ wyjściem .c jest ciąg znaków, a nie więcej JSON. Jak sprawić, by jq przeanalizował ten ciąg?

Moje pierwsze rozwiązanie jest użycie sed zastąpić wszystkie znaki ewakuacyjne ( \":\", \",\"i \"), ale to jest brudny, zakładam istnieje sposób wbudowane jqto zrobić?

Dzięki!

edycja: Również dostępna tutaj wersja jq to:

$ jq --version
jq version 1.3

Myślę, że w razie potrzeby mógłbym to zaktualizować.

Colin Grogan
źródło
To pytanie jest również pomocne, jeśli szukasz: „Jak usunąć ciąg json za pomocą jq?”
k0pernikus

Odpowiedzi:

165

jq ma fromjsonwbudowaną obsługę :

jq '.c | fromjson | .id' myFile.json

fromjson został dodany w wersji 1.4.

jwodder
źródło
2
Dziękuję Ci. To działa. Przyjmuję tę odpowiedź, ponieważ wydaje mi się bardziej „idiomaicka”. Twoje zdrowie.
Colin Grogan
@ColinGrogan, proszę.
vbence
@ColinGrogan: Nie widzę powodu, aby zmieniać zaakceptowaną odpowiedź, ponieważ w swoim pytaniu wyraźnie napisałeś, że korzystałeś z wersji 1.3 jq, w której ta fromjsonfunkcja nie jest dostępna. Innymi słowy, nawet jeśli ta odpowiedź jest interesująca, nie odpowiada na pytanie.
Casimir et Hippolyte
Czy można tego użyć, ale na całym pliku json (bez określania właściwości .id)?
Florian Castelain
1
@FlorianCastelain tak, pomiń go lub użyj kropki jq 'fromjson | .' myfile"{\"key\":1, \"word\":\"cat\"}"
41

Możesz użyć nieprzetworzonego wyjścia (-r), które spowoduje cofnięcie znaków:

jq -r .c myfile.json | jq .id

DODATEK: Ma tę zaletę, że działa w jq 1.3 i nowszych; w rzeczywistości powinno działać w każdej wersji jq, która ma opcję -r.

Casimir et Hippolyte
źródło