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)

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

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

Isso parece desnecessário. Resposta alternativa fornecida
cricket_007
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.