
Digamos que tengo un JSON como el siguiente:
{
"key1": {
"keyA": "1",
"keyB": "null",
"keyC": "null"
},
"key2": {
"keyA": "null",
"keyB": "3",
"keyC": "null"
}
}
Me gustaría encontrar una manera de excluir todas las claves con el valor null
en mi JSON. Entonces el resultado sería el siguiente:
{
"key1": {
"keyA": "1"
},
"key2": {
"keyB": "3"
}
}
Sé que puedo excluir claves específicas con sus nombres usando jq
, por ejemplo cat myjson.json | jq 'del(.[]|.keyA)'
, esto borrará todas mis keyA
claves dentro del json, pero quiero excluir las claves según sus valores... ¿Cómo puedo excluir todas las claves con valor "null"
usando jq
?
Respuesta1
del(..|select(. == "null"))
Esto utiliza eloperador de descenso recursivo..
yselect
funciónpara encontrar todas las ubicaciones en cualquier parte del objeto con valores que sean iguales "null"
y les proporcione del
. select
evalúa una expresión booleana para decidir si incluye un valor particular o no, mientras ..
le asigna cada valor en el árbol y del
acepta cualquier expresión que produzca ubicaciones, lo cual hace. (manifestación)
Puede utilizar la path
función para comprobar lo que está encontrando:
path(..|select(. == "null"))
y depura lo que cree que estás intentando eliminar primero. Elproducciónes una matriz de claves a seguir de forma recursiva para alcanzar el valor, por lo que el elemento final de la matriz es la clave que realmente se eliminaría.
También puede usar update-assignment |= empty
en jq 1.6 y versiones posteriores (falla silenciosamente en versiones anteriores). Puede que esto le resulte más claro o no: (..|select(. == "null")) |= empty
(manifestación) elimina esas mismas claves.
Si sus valores son true null
s, en lugar de la cadena "null"
, puede usar la nulls
función incorporada en lugar del conjunto select
:.del(..|nulls)
Si sus valores son verdaderos nulosyestas usandojq 1.5(la versión actual en muchas distribuciones), necesitarás usar recurse(.[]?; true)
en lugar de ..
. Esto se debe a que los valores nulos están específicamente excluidos ..
(porquese define comorecurse
, cualSe define como recurse(.[]?)
, que se define como recurse(.[]?; . != null)
). Este comportamiento cambió al (más útil) anterior en 1.6, aunquela documentaciónno ha cambiado, lo cualparece ser un error de documentación.
Respuesta2
Suponiendo que sabe que desea probar los valores en el segundo nivel:
jq 'del(.[][] | select(. == "null"))' file
Esto elimina todos los pares clave-valor en el segundo nivel desde arriba, donde el valor es la cadena literal null
.
Dado el documento en la pregunta, esto produce el resultado esperado.
Usando una versión jq
posterior a la 1.5, también puedes actualizar los datos a los bits que no tienen el null
valor:
jq '.[][] |= select(. != "null")' file