Começando com um corretamente formado e um MWE completo:
{
"stock": {
"type": "str",
"properties": {
"warehouse": {
"type": 123
},
"retail": {
"type": false
}
}
}
}
Em seguida, use jq
(v1.5):
$ jq -M -c 'path(..|.type?//empty) | join(".")' mwe.json
"stock.type"
"stock.properties.warehouse.type"
(adicione -r
para omitir aspas na saída, -M
e -c
são apenas para formatar a saída). Isso recorre pela estrutura ( ..
) procurando por um índice ou chave de "tipo", suprime erros ( ?
) quando isso não é apropriado e avalia como "vazio" ( //
) quando o valor é falso ou null, então nivela ( join()
) o array de caminho.
Um possível problema é que um valor false
(ou nulo) aciona empty
(pelo menos na v1.5, mas não na v1.4) e o item stock.properties.retail.type
é omitido.
Sem o | join(".")
, você receberá matrizes JSON, o que também pode ser útil:
["stock","type"]
["stock","properties","warehouse","type"]
Uma versão mais complexa, incluindo os valores:
$ jq -M -c '[paths(.|select(type=="object" and has("type")) )][] \
as $path | [$path+["type"], getpath($path + ["type"])]' mwe.json
[["stock","type"],"str"]
[["stock","properties","warehouse","type"],123]
[["stock","properties","retail","type"],false]
Isto é um pouco mais elegante, cria um array selecionando todos os objetos que possuem um filho "type", depois imprime o caminho para "type" e seu valor.