
Digamos que eu tenha um JSON como o seguinte:
{
"key1": {
"keyA": "1",
"keyB": "null",
"keyC": "null"
},
"key2": {
"keyA": "null",
"keyB": "3",
"keyC": "null"
}
}
Gostaria de encontrar uma maneira de excluir todas as chaves com o valor null
no meu JSON. Então o resultado seria o seguinte:
{
"key1": {
"keyA": "1"
},
"key2": {
"keyB": "3"
}
}
Eu sei que posso excluir chaves específicas com seus nomes usando jq
, por exemplo cat myjson.json | jq 'del(.[]|.keyA)'
, isso apagará todas as minhas keyA
chaves dentro do json, mas quero excluir as chaves de acordo com seus valores... Como posso excluir todas as chaves com valor "null"
usando jq
?
Responder1
del(..|select(. == "null"))
Isso usa ooperador de descida recursiva..
eselect
funçãopara encontrar todos os locais em qualquer lugar do objeto com valores iguais "null"
e fornecê-los a del
. select
avalia uma expressão booleana para decidir se deve incluir um valor específico ou não, enquanto ..
fornece a ela todos os valores da árvore e del
aceita qualquer expressão que produza localizações, o que ocorre. (demonstração)
Você pode usar a path
função para verificar o que está encontrando:
path(..|select(. == "null"))
e depure o que você acha que você está tentando excluir primeiro. Osaídaé uma matriz de chaves a serem seguidas recursivamente para atingir o valor e, portanto, o item final da matriz é a chave que realmente seria excluída.
Você também pode usar update-assignment |= empty
no jq 1.6 e superior (ele falha silenciosamente em versões anteriores). Você pode ou não achar isso mais claro: (..|select(. == "null")) |= empty
(demonstração) exclui essas mesmas chaves.
Se seus valores forem true null
s, em vez de string "null"
, você pode usar a nulls
função interna no lugar do inteiro select
: del(..|nulls)
.
Se seus valores forem verdadeiros nulosevocê está usandojq 1,5(a versão atual em muitas distribuições), você precisará usar recurse(.[]?; true)
no lugar de ..
. Isso ocorre porque os valores nulos são especificamente excluídos ..
(porqueé definido comorecurse
, qualé definido como recurse(.[]?)
, que é definido como recurse(.[]?; . != null)
). Este comportamento mudou para o (mais útil) acima em 1.6, emboraa documentaçãonão mudou, o queparece ser um bug de documentação.
Responder2
Supondo que você saiba que deseja testar os valores no 2º nível:
jq 'del(.[][] | select(. == "null"))' file
Isso exclui todos os pares de valores-chave no segundo nível a partir do topo, onde o valor é a string literal null
.
Dado o documento em questão, isso produz o resultado esperado.
Usando uma versão jq
mais recente que 1.5, você também pode atualizar os dados para os bits que não possuem o null
valor:
jq '.[][] |= select(. != "null")' file