Estoy usando las herramientas jq (jq-json-processor) en el script de shell para analizar json.
Tengo 2 archivos json y quiero combinarlos en un archivo único
Aquí el contenido de los archivos:
archivo1
{
"value1": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value1": "v1",
"value2": "v2"
},
"bbb": {
"value1": "v1",
"value2": "v2"
},
"ccc": {
"value1": "v1",
"value2": "v2"
}
}
}
archivo2
{
"status": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value3": "v3",
"value4": 4
},
"bbb": {
"value3": "v3"
},
"ddd": {
"value3": "v3",
"value4": 4
}
}
}
Resultado Esperado
{
"value": {
"aaa": {
"value1": "v1",
"value2": "v2",
"value3": "v3",
"value4": 4
},
"bbb": {
"value1": "v1",
"value2": "v2",
"value3": "v3"
},
"ccc": {
"value1": "v1",
"value2": "v2"
},
"ddd": {
"value3": "v3",
"value4": 4
}
}
}
Intento muchas combinaciones, pero el único resultado que obtengo es el siguiente, que no es el resultado esperado:
{
"ccc": {
"value2": "v2",
"value1": "v1"
},
"bbb": {
"value2": "v2",
"value1": "v1"
},
"aaa": {
"value2": "v2",
"value1": "v1"
}
}
{
"ddd": {
"value4": 4,
"value3": "v3"
},
"bbb": {
"value3": "v3"
},
"aaa": {
"value4": 4,
"value3": "v3"
}
}
Usando este comando:
jq -s '.[].value' file1 file2
json
shell
command-line
jq
Janfy
fuente
fuente
json
uso:cat f1 f2 | json --deep-merge
json
@ xer0x?json
herramienta, vaya a github.com/trentm/jsonRespuestas:
Desde 1.4 esto ahora es posible con el
*
operador. Cuando se le dan dos objetos, los fusionará de forma recursiva. Por ejemplo,Importante: tenga en cuenta la
-s (--slurp)
bandera, que coloca los archivos en la misma matriz.Te conseguiría:
Si también desea deshacerse de las otras claves (como su resultado esperado), una forma de hacerlo es esta:
O el presumiblemente algo más eficiente (porque no combina ningún otro valor):
fuente
-s
bandera es importante ya que sin ella los dos objetos no están en una matriz.Utilizar
jq -s add
:Esto lee todos los textos JSON de stdin en una matriz (
jq -s
hace eso) y luego los "reduce".(
add
se define comodef add: reduce .[] as $x (null; . + $x);
, que itera sobre los valores de la matriz de entrada / objeto y los agrega. Suma de objetos == fusionar).fuente
reduce .[] as $x ({}; . * $x)
, vea también la respuesta de jrib .Quién sabe si todavía lo necesita, pero aquí está la solución.
Una vez que llegue a la
--slurp
opción, ¡es fácil!Entonces el
+
operador hará lo que quiera:(Nota: si desea fusionar objetos internos en lugar de simplemente sobrescribir los del archivo izquierdo con los del archivo derecho, deberá hacerlo manualmente)
fuente
Aquí hay una versión que funciona de forma recursiva (usando
*
) en una cantidad arbitraria de objetos:fuente
jq -s 'reduce .[] as $item ({}; . * $item)' *.json
Primero, {"value": .value} se puede abreviar a solo {value}.
En segundo lugar, la opción --argfile (disponible en jq 1.4 y jq 1.5) puede ser de interés ya que evita tener que usar la opción --slurp.
Al juntarlos, los dos objetos de los dos archivos se pueden combinar de la forma especificada de la siguiente manera:
La bandera '-n' le dice a jq que no lea desde stdin, ya que las entradas provienen de las opciones --argfile aquí.
fuente
--argile
por--slurpfile
Esto se puede usar para fusionar cualquier número de archivos especificados en el comando:
jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json
o esto para cualquier cantidad de archivos
jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json
fuente