Используйте jq для анализа строки JSON

87

Я пытаюсь jqразобрать структуру JSON, например:

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

То есть элемент в JSON - это строка с экранированным json.

Итак, у меня есть что-то вроде $ jq [.c] myFile.json | jq [.id]

Но это сбой с jq: error: Cannot index string with string

Это потому, что вывод .c - это строка, а не JSON. Как мне заставить jq проанализировать эту строку?

Мое первоначальное решение - использовать sed для замены всех escape-символов ( \":\", \",\"и \"), но это беспорядочно, я предполагаю, что есть встроенный способ jqсделать это?

Благодарность!

edit: Кроме того, здесь доступна версия jq:

$ jq --version
jq version 1.3

Думаю, я могу обновить его, если потребуется.

Колин Гроган
источник
Этот вопрос также помогает, если вы ищете: «Как отключить экранирование строки json с помощью jq?»
k0pernikus

Ответы:

165

jq имеет fromjsonвстроенную функцию для этого:

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

fromjson был добавлен в версии 1.4.

Jwodder
источник
2
Спасибо. Это работает. Я приму этот ответ, поскольку я считаю его более «идиомайтным». Ура.
Колин Гроган,
@ColinGrogan, пожалуйста.
vbence
@ColinGrogan: Я не вижу причин менять принятый ответ, поскольку вы четко написали в своем вопросе, что использовали версию 1.3 jq, в которой эта fromjsonфункция недоступна. Другими словами, даже если этот ответ интересен, он не отвечает на вопрос.
Casimir et Hippolyte
Можно ли использовать это, но для всего файла json (без указания свойства .id)?
Флориан
1
@FlorianCastelain да, либо опустите его, либо используйте точку:, jq 'fromjson | .' myfileгде myfile содержит"{\"key\":1, \"word\":\"cat\"}"
41

Вы можете использовать необработанный вывод (-r), который отключит экранирование символов:

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

ДОПОЛНЕНИЕ: это имеет то преимущество, что работает в jq 1.3 и выше; действительно, он должен работать во всех версиях jq, у которых есть опция -r.

Казимир и Ипполит
источник