Validación de archivos JSON en Ubuntu desde la línea de comandos

Estoy buscando un programa de línea de comandos fuera de línea que pueda validar archivos JSON en Ubuntu: tengo una carpeta que contiene una lista de archivos JSON, algunos posiblemente dañados, por lo que tendría que tener la lista de archivos JSON dañados.

¿Está por casualidad ejecutando PHP en esa máquina Ubuntu? Si es así, y solo desea separar el trigo de la paja: for json in folder/*; do echo $json; php -r "\$foo=json_decode(file_get_contents('$json'));"; doneesto hará eco de todos los nombres de archivo seguidos de errores para ese archivo si hay alguno ; de lo contrario, solo el nombre de archivo. Ajuste para la perfección: for json in folder/*; do php -r "if ( ! \$foo=json_decode(file_get_contents('$json')) ) echo \"$json has errors\n\";"; done, que solo enumeraría los archivos dañados.
@Izzy Gracias, estoy ejecutando PHP en una máquina, así que eso también funciona :) Puede publicarlo como respuesta.
Listo, Franck, incluida una explicación para los no tan técnicos que todavía quieren probarlo :) ¡Disfrútalo!

Respuestas (2)

Sin la necesidad de una aplicación específica, si solo desea separar el trigo de la paja y tiene PHP instalado en la máquina Linux, puede usar una sola línea para esto:

for json in folder/*; do php -r "if ( ! \$foo=json_decode(file_get_contents('$json')) ) echo \"$json\n\";"; done

Esto listaría todos los archivos rotos .json en el directorio llamado folder. Quite el signo de exclamación ( !) para enumerar solo los .jsonarchivos que están bien.

Bien podría ser que PHP escupe algún mensaje de error adicional aquí. Si eso sucede, simplemente redirija la salida de error (STDERR) al agujero negro de la máquina ( /dev/null):

for json in folder/*; do php -r "if ( ! \$foo=json_decode(file_get_contents('$json')) ) echo \"$json\n\";" 2>/dev/null; done

TL; DR: una breve explicación de lo que hace ese one-liner

  • for json in folder/*; do […] done: recorrer todos los .jsonarchivos en la ubicación dada. En cada iteración, almacene el nombre del archivo en una variable llamada $json.
  • php -r: invocar el ejecutable de PHP. El -rparámetro le dice que (r) ejecute un comando en lugar de esperar un archivo. El comando debe seguir directamente a esto, separado por espacios en blanco.
  • "[…]": usando comillas dobles, podemos integrar más fácilmente las variables de shell. El precio es que tenemos que escapar de todos los $signos que pertenecen a las variables de PHP.
  • \$foo: ver punto anterior, necesitamos escapar del $aquí.
  • $foo=json_decode(file_get_contents('$json')): haga que PHP lea el archivo ( file_get_contents; $jsonaquí está nuestra variable Bash del primer punto), luego convierta el JSON en un objeto PHP ( json_decode). No queremos ver el resultado, así que lo asignamos a una variable ( $fooen mi ejemplo).
    Si la decodificación fue exitosa, la asignación devolverá TRUE; de lo contrario FALSE, es por eso que podemos usar esta construcción como nuestra "condición if".
  • if ( […] ) echo \"$json\n\";": solo escriba el nombre del archivo (esta es nuevamente nuestra variable Bash aquí) en la consola si se cumple nuestra condición: "separar el trigo de la paja", como lo dije inicialmente. Como es habitual en PHP, el comando debe terminar con un punto y coma ( ;). También tenga en cuenta que necesitaba escapar de las comillas dobles aquí, para que nuestro "envoltorio externo de Shell" no termine prematuramente. Necesitaba las comillas dobles, por lo que \nse interpreta como "nueva línea": con comillas simples, imprimiría un literal \nen su lugar.
  • 2>/dev/null: Redirigir la salida de error (STDERR) al "agujero negro" (es decir, no mostrar ningún error si se produce). Nuestros echocomandos van a STDOUT y, por lo tanto, no se ven afectados por esto.

Puedes usar jsonlint :

  • CLI
  • código abierto (escrito en JavaScript)
  • compruebe si los archivos son válidos:

Ejemplo:

# Install
sudo apt-get install -y nodejs npm
sudo npm install jsonlint -g
sudo ln -s /usr/bin/nodejs /usr/bin/node # to avoid "/usr/bin/env: node: No such file or directory" error
jsonlint -qc *.json

# Use
ubuntu@pm:~/pubmed/pubmed$ jsonlint --compact --validate *.json
my_file_bad.json: line 279916, col 18, found: 'EOF' - expected: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['.
ubuntu@pm:~/pubmed/pubmed$

Opciones útiles:

   -c, --compact            compact error display
   -V, --validate           a JSON schema to use for validation