Presta atención ya que en esta división hallarás el arreglo que buscas.
Solución:
En principio, si tiene acceso a bash o algún otro shell avanzado, podría hacer algo como
cmp <(jq -cS . A.json) <(jq -cS . B.json)
utilizando subprocesos. Esto formateará el json con ordenado keysy representación consistente de puntos flotantes. Esas son las únicas dos razones por las que puedo pensar por qué json con el mismo contenido se imprimiría de manera diferente. Por lo tanto haciendo un simple string la comparación posterior dará como resultado una prueba adecuada. Probablemente también valga la pena señalar que si no puede usar bash, puede obtener los mismos resultados con archivos temporales, solo que no es tan limpio.
Esto no responde del todo a su pregunta, porque en la forma en que planteó la pregunta que quería ["John", "Bryan"]
y ["Bryan", "John"]
para comparar de forma idéntica. Dado que json no tiene el concepto de un conjunto, solo una lista, deben considerarse distintos. El orden es importante para las listas. Tendría que escribir alguna comparación personalizada si quisiera que se compararan por igual, y para hacer eso necesitaría definir lo que quiere decir con igualdad. ¿Importa el orden para todas las listas o solo para algunas? ¿Qué pasa con los elementos duplicados? Alternativamente, si desea que se representen como un conjunto y los elementos son cadenas, puede colocarlos en objetos como "John": null, "Bryan": null
. El orden no importará cuando se comparen los de igualdad.
Actualizar
De la discusión de comentarios: si desea tener una mejor idea de por qué el json no es el mismo, entonces
diff <(jq -S . A.json) <(jq -S . B.json)
producirá una salida más interpretable. vimdiff
podría ser preferible diferir dependiendo de los gustos.
Dado que la comparación de jq ya compara objetos sin tener en cuenta key ordenar, todo lo que queda es ordenar todas las listas dentro del objeto antes de compararlas. Suponiendo que sus dos archivos se nombran a.json
y b.json
en el último jq nightly:
jq --argfile a a.json --argfile b b.json -n '($a | (.. | arrays) |= sort) as $a | ($b | (.. | arrays) |= sort) as $b | $a == $b'
Este programa debería devolver "true" o "false"dependiendo de si los objetos son iguales o no utilizando la definición de igualdad que solicita.
EDITAR: El (.. | arrays) |= sort
La construcción en realidad no funciona como se esperaba en algunos casos extremos. Este problema de GitHub explica por qué y proporciona algunas alternativas, como:
def post_recurse(f): def r: (f | select(. != null) | r), .; r; def post_recurse: post_recurse(.[]?); (post_recurse | arrays) |= sort
Aplicado a la invocación jq anterior:
jq --argfile a a.json --argfile b b.json -n 'def post_recurse(f): def r: (f | select(. != null) | r), .; r; def post_recurse: post_recurse(.[]?); ($a | (post_recurse | arrays) |= sort) as $a | ($b | (post_recurse | arrays) |= sort) as $b | $a == $b'
Usar jd
con el -set
opción:
Sin salida significa que no hay diferencia.
$ jd -set A.json B.json
Las diferencias se muestran como una ruta @ y + o -.
$ jd -set A.json C.json
@ ["People",]
+ "Carla"
Los diferenciales de salida también se pueden usar como archivos de parche con el -p
opción.
$ jd -set -o patch A.json C.json; jd -set -p patch B.json
"City":"Boston","People":["John","Carla","Bryan"],"State":"MA"
https://github.com/josephburnett/jd#command-line-usage
Acuérdate de que puedes optar por la opción de reseñar tu experiencia si encontraste tu atascamiento .