Como converter string json incorporada (entre aspas) para json

22

Eu estou familiarizado com "jq" para analisar json.

Eu trabalho com um serviço que produz uma resposta json em que uma das propriedades é uma string json. Como converter esse valor citado em uma string json válida para que eu possa processá-lo com jq?

Por exemplo, se eu apenas visualizar o json bonito e impresso de "jq.", Aqui está um pequeno trecho da saída:

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

Posso usar jq para obter o valor dessa propriedade, mas preciso converter a cadeia de caracteres citada em json válido "desescapando".

Suponho que eu possa canalizá-lo para o sed, removendo as aspas duplas de abertura e final e removendo todas as barras invertidas (" sed -e 's/^"//' -e 's/"$//' -e 's/\\//g'"). Isso parece funcionar, mas não parece ser a solução mais robusta.

Atualização :

Apenas para esclarecer um pouco o que estou fazendo, aqui estão algumas amostras elididas que mostram o que tentei:

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

Atualização :

Aqui está um exemplo completamente independente:

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

Atualização :

Se eu tentasse processar essa última saída com uma expressão jq real, ele faria algo assim:

% 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)
David M. Karr
fonte
Se você usar jqpara obter apenas o valor da propriedade de cadeia, não é devolvê-lo unescaped? Se assim for, basta colocar isso em um novo jq.
DopeGhoti
Não, ele não o retorna sem escape. Essa é a questão.
David M. Karr
Que tal echo $(jq statement here)?
DopeGhoti 8/0118
Não, nenhuma mudança.
David M. Karr
@ DavidM.Karr, ok, se possível - prolongar a sua entrada com a corda fundamental real eo resultado final
RomanPerekhrest

Respostas:

20

Há uma rawbandeira para isso

    -r      output raw strings, not JSON texts;

jq -rc .stuff stuff.json

Saída

{"date":"2018-01-08"}
cricket_007
fonte
A diferença é que, com a resposta de Roman, você garante uma saída JSON válida ou mensagens de erro, se não for JSON válido.
Kusalananda
Ponto válido, mas se isso estiver sendo usado na automação, acho que seria incomum repentinamente não ter saída json válida. A forma mais conveniente ficará perfeitamente bem quase o tempo todo. Ainda é bom saber sobre métodos mais precisos, no entanto.
precisa
@ DavidM.Karr "incomum de repente não ter saída json válida" HA! Riiiight. Tratamento de erros na automação? Erros nunca acontecerão! Porque se importar!
Bruno Bronosky
Isso requer canalização para outro jqpara processamento JSON adicional, enquanto que com a abordagem de Roman você pode continuar a mesma jqexpressão.
Raman
1
@ cricket_007: tentei com o jq 1.5 e confirmou que não funciona: jq -rc '.stuff.date'produz jq: error (at <stdin>:0): Cannot index string with string "date". No entanto: .stuff | fromjson | .datefunciona bem.
Raman
26

Com jqa fromjsonfunção:

stuff.jsonConteúdo da amostra :

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

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

A saída:

{"date":"2018-01-08"}
RomanPerekhrest
fonte
Isso parece desnecessário. Resposta alternativa fornecida
cricket_007