¿Cómo puedo imprimir bastante JSON en un script de shell (Unix)?

¿Existe un script de shell (Unix) para formatear JSON en forma legible por humanos?

Básicamente, quiero que transforme lo siguiente:

{ "foo": "lorem", "bar": "ipsum" } 

… en algo como esto:

 { "foo": "lorem", "bar": "ipsum" } 

Con Python 2.6+ puedes hacer lo siguiente:

 echo '{"foo": "lorem", "bar": "ipsum"}' | python -m json.tool 

o, si el JSON está en un archivo, puede hacer:

 python -m json.tool my_json.json 

si el JSON proviene de una fuente de Internet, como una API, puede usar

 curl http://my_url/ | python -m json.tool 

Para mayor comodidad en todos estos casos, puede hacer un alias:

 alias prettyjson='python -m json.tool' 

Para una mayor comodidad con un poco más de tipeo para que esté listo:

 prettyjson_s() { echo "$1" | python -m json.tool } prettyjson_f() { python -m json.tool "$1" } prettyjson_w() { curl "$1" | python -m json.tool } 

para todos los casos anteriores. Puede poner esto en .bashrc y estará disponible cada vez en shell. prettyjson_s '{"foo": "lorem", "bar": "ipsum"}' como prettyjson_s '{"foo": "lorem", "bar": "ipsum"}' .

Puede usar: jq

¡Es muy simple de usar y funciona genial! Puede manejar estructuras JSON muy grandes, incluidas las secuencias. Puedes encontrar sus tutoriales aquí .

Aquí hay un ejemplo:

 $ jq . <<< '{ "foo": "lorem", "bar": "ipsum" }' { "bar": "ipsum", "foo": "lorem" } 

O en otras palabras:

 $ echo '{ "foo": "lorem", "bar": "ipsum" }' | jq . { "bar": "ipsum", "foo": "lorem" } 

Utilizo el argumento “espacio” de JSON.stringify para imprimir bastante JSON en JavaScript.

Ejemplos:

 // Indent with 4 spaces JSON.stringify({"foo":"lorem","bar":"ipsum"}, null, 4); // Indent with tabs JSON.stringify({"foo":"lorem","bar":"ipsum"}, null, '\t'); 

Desde la línea de comandos de Unix con nodejs, especificando json en la línea de comando:

 $ node -e "console.log(JSON.stringify(JSON.parse(process.argv[1]), null, '\t'));" \ '{"foo":"lorem","bar":"ipsum"}' 

Devoluciones:

 { "foo": "lorem", "bar": "ipsum" } 

Desde la línea de comandos de Unix con Node.js, especificando un nombre de archivo que contiene JSON, y usando un sangría de cuatro espacios:

 $ node -e "console.log(JSON.stringify(JSON.parse(require('fs') \ .readFileSync(process.argv[1])), null, 4));" filename.json 

Usando una tubería:

 echo '{"foo": "lorem", "bar": "ipsum"}' | node -e \ "\ s=process.openStdin();\ d=[];\ s.on('data',function(c){\ d.push(c);\ });\ s.on('end',function(){\ console.log(JSON.stringify(JSON.parse(d.join('')),null,2));\ });\ " 

Escribí una herramienta que tiene uno de los mejores formateadores de “espacios en blanco inteligentes” disponibles. Produce un resultado más legible y menos detallado que la mayoría de las otras opciones aquí.

underscore-cli

Así es como se ve el “espacio en blanco inteligente”:

Puede ser un poco parcial, pero es una herramienta increíble para imprimir y manipular datos JSON desde la línea de comandos. Es súper amigable de usar y tiene una extensa ayuda / documentación de línea de comandos. Es una razor suiza que utilizo para 1001 pequeñas tareas diferentes que sería sorprendentemente molesto hacer de otra manera.

Último caso de uso: Chrome, consola Dev, pestaña Red, exportar todo como archivo HAR, “cat site.har | subrayar seleccionar ‘.url’ –outfmt texto | grep mydomain”; ahora tengo una lista ordenada cronológicamente de todas las búsquedas de URL realizadas durante la carga del sitio de mi empresa.

La impresión bonita es fácil:

 underscore -i data.json print 

La misma cosa:

 cat data.json | underscore print 

Lo mismo, más explícito:

 cat data.json | underscore print --outfmt pretty 

Esta herramienta es mi proyecto de pasión actual, por lo que si tiene alguna solicitud de funciones, es muy probable que las aborde.

Usualmente solo hago:

 echo '{"test":1,"test2":2}' | python -mjson.tool 

Y para recuperar datos seleccionados (en este caso, el valor de “prueba”):

 echo '{"test":1,"test2":2}' | python -c 'import sys,json;data=json.loads(sys.stdin.read()); print data["test"]' 

Si los datos JSON están en un archivo:

 python -mjson.tool filename.json 

Si desea hacerlo todo de una vez con curl en la línea de comando usando un token de autenticación:

 curl -X GET -H "Authorization: Token wef4fwef54te4t5teerdfgghrtgdg53" http://testsite/api/ | python -mjson.tool 

Gracias a los consejos muy útiles de JF Sebastian, aquí hay un script ligeramente mejorado que he encontrado:

 #!/usr/bin/python """ Convert JSON data to human-readable form. Usage: prettyJSON.py inputFile [outputFile] """ import sys import simplejson as json def main(args): try: if args[1] == '-': inputFile = sys.stdin else: inputFile = open(args[1]) input = json.load(inputFile) inputFile.close() except IndexError: usage() return False if len(args) < 3: print json.dumps(input, sort_keys = False, indent = 4) else: outputFile = open(args[2], "w") json.dump(input, outputFile, sort_keys = False, indent = 4) outputFile.close() return True def usage(): print __doc__ if __name__ == "__main__": sys.exit(not main(sys.argv)) 

En * nix, leer de stdin y escribir en stdout funciona mejor:

 #!/usr/bin/env python """ Convert JSON data to human-readable form. (Reads from stdin and writes to stdout) """ import sys try: import simplejson as json except: import json print json.dumps(json.loads(sys.stdin.read()), indent=4) sys.exit(0) 

Pon esto en un archivo (nombré al mío “prettyJSON” después de la respuesta de AnC ) en tu PATH y chmod +x it, y ya estás listo.

Con Perl, use el módulo CPAN JSON::XS . Instala una herramienta de línea de comandos json_xs .

Validar:

 json_xs -t null < myfile.json 

Pretifique el archivo JSON src.json a pretty.json :

 < src.json json_xs > pretty.json 

Si no tienes json_xs , prueba json_pp . "pp" es para "perl puro": la herramienta se implementa solo en Perl, sin un enlace a una biblioteca C externa (que es lo que significa XS, el "Sistema de extensión" de Perl).

Si usa npm y Node.js, puede hacer npm install -g json y luego canalizar el comando a través de json . Haz json -h para obtener todas las opciones. También puede extraer campos específicos y colorear el resultado con -i .

 curl -s http://search.twitter.com/search.json?q=node.js | json 

La JSON Ruby Gem se incluye con un script de shell para embellecer JSON:

 sudo gem install json echo '{ "foo": "bar" }' | prettify_json.rb 

Descarga de scripts: gist.github.com/3738968

No es demasiado simple con una forma nativa con las herramientas jq .

Por ejemplo:

 cat xxx | jq . 

ACTUALIZAR Estoy usando jq ahora como se sugirió en otra respuesta. Es extremadamente potente en el filtrado de JSON, pero, en su forma más básica, también es una manera increíble de imprimir bastante JSON para ver.

jsonpp es una linda impresora de línea de comandos JSON.

Del LÉAME:

Bastante imprime las respuestas del servicio web como estas:

 curl -s -L http://t.co/tYTq5Pu | jsonpp 

y haz hermosos los archivos que corren en tu disco:

 jsonpp data/long_malformed.json 

Si tienes Mac OS X, puedes brew install jsonpp . Si no, simplemente puede copiar el binario en algún lugar de su $PATH .

Prueba pjson . ¡Tiene colores!

echo '{

Instalarlo con pip :

⚡ pip install pjson

Y luego canalizar cualquier contenido JSON a pjson .

 $ echo '{ "foo": "lorem", "bar": "ipsum" }' \ > | python -c'import fileinput, json; > print(json.dumps(json.loads("".join(fileinput.input())), > sort_keys=True, indent=4))' { "bar": "ipsum", "foo": "lorem" } 

NOTA: No es la forma de hacerlo.

Lo mismo en Perl:

 $ cat json.txt \ > | perl -0007 -MJSON -nE'say to_json(from_json($_, {allow_nonref=>1}), > {pretty=>1})' { "bar" : "ipsum", "foo" : "lorem" } 

Nota 2: si corres

 echo '{ "Düsseldorf": "lorem", "bar": "ipsum" }' \ | python -c'import fileinput, json; print(json.dumps(json.loads("".join(fileinput.input())), sort_keys=True, indent=4))' 

la palabra muy legible se convierte en codificada

 { "D\u00fcsseldorf": "lorem", "bar": "ipsum" } 

Si el rest de su canalización manejará elegantemente unicode y le gustaría que su JSON también sea amigable para los humanos, simplemente use ensure_ascii=False

 echo '{ "Düsseldorf": "lorem", "bar": "ipsum" }' \ | python -c'import fileinput, json; print json.dumps(json.loads("".join(fileinput.input())), sort_keys=True, indent=4, ensure_ascii=False)' 

y obtendrás:

 { "Düsseldorf": "lorem", "bar": "ipsum" } 

Yo uso jshon para hacer exactamente lo que describes. Solo corre:

 echo $COMPACTED_JSON_TEXT | jshon 

También puede pasar argumentos para transformar los datos JSON.

Echa un vistazo a Jazor . Es un analizador JSON de línea de comando simple escrito en Ruby.

 gem install jazor jazor --help 

O bien, con Ruby:

 echo '{ "foo": "lorem", "bar": "ipsum" }' | ruby -r json -e 'jj JSON.parse gets' 

Así es como lo hago:

 curl yourUri | json_pp 

Acorta el código y hace el trabajo.

Simplemente canalice la salida a jq . .

Ejemplo:

 twurl -H ads-api.twitter.com '.......' | jq . 

JSONLint tiene una implementación de código abierto en github que se puede usar en la línea de comandos o se puede incluir en un proyecto node.js.

 npm install jsonlint -g 

y entonces

 jsonlint -p myfile.json 

o

 curl -s "http://api.twitter.com/1/users/show/user.json" | jsonlint | less 

Pygramize

Yo combino la json.tool de Python con pygramize:

 echo '{"foo": "bar"}' | python -m json.tool | pygmentize -g 

Hay algunas alternativas a pygramize que se enumeran en mi esta respuesta .

Aquí hay una demostración en vivo:

Manifestación

Recomiendo usar la utilidad de línea de comandos json_xs que se incluye en el módulo JSON :: XS perl. JSON :: XS es ​​un módulo Perl para serializar / deserializar JSON, en una máquina Debian o Ubuntu puede instalarlo así:

 sudo apt-get install libjson-xs-perl 

Obviamente también está disponible en CPAN .

Para usarlo para formatear JSON obtenido de una URL, puede usar curl o wget de la siguiente manera:

 $ curl -s http://page.that.serves.json.com/json/ | json_xs 

o esto:

 $ wget -q -O - http://page.that.serves.json.com/json/ | json_xs 

y para formatear JSON contenido en un archivo, puede hacer esto:

 $ json_xs < file-full-of.json 

Para volver a formatear como YAML , que algunas personas consideran que es más humanamente legible que JSON:

 $ json_xs -t yaml < file-full-of.json 

Vanilla Bash

Un script simple de Bash ( grep / awk ) para una bonita impresión JSON, sin instalación de terceros:

json_pretty.sh

 #/bin/bash grep -Eo '"[^"]*" *(: *([0-9]*|"[^"]*")[^{}\["]*|,)?|[^"\]\[\}\{]*|\{|\},?|\[|\],?|[0-9 ]*,?' | awk '{if ($0 ~ /^[}\]]/ ) offset-=4; printf "%*c%s\n", offset, " ", $0; if ($0 ~ /^[{\[]/) offset+=4}' 

Ejemplos:

1) Leer archivo e imprimir bonito en la consola

 cat file.json | json_pretty.sh 

2) Usar con Windows GIT Bash de archivo a archivo (basado en UTF8):

 cat fileIn.json |sh.exe json_pretty.sh > fileOut.json 

Con Perl, si instala JSON :: PP desde CPAN obtendrá el comando json_pp . Robando el ejemplo de B Bycroft obtienes:

 [pdurbin@beamish ~]$ echo '{"foo": "lorem", "bar": "ipsum"}' | json_pp { "bar" : "ipsum", "foo" : "lorem" } 

Vale la pena mencionar que json_pp viene preinstalado con Ubuntu 12.04 (al menos) y Debian en /usr/bin/json_pp

  1. brew install jq
  2. command + | jq
  3. (ejemplo: curl localhost:5000/blocks | jq )
  4. ¡Disfrutar!

enter image description here

Instala yajl-tools con el siguiente comando:

sudo apt-get install yajl-tools

entonces,

echo '{"foo": "lorem", "bar": "ipsum"}' | json_reformat

yajl es muy agradable, en mi experiencia. Utilizo su comando json_reformat para imprimir .json archivos .json en vim poniendo la siguiente línea en mi .vimrc :

 autocmd FileType json setlocal equalprg=json_reformat 

jj es superrápido, puede manejar documentos descomunales JSON de forma económica, no estropea números JSON válidos, y es fácil de usar, por ejemplo

 jj -p # for reading from STDIN 

o

 jj -p -i input.json 

Es (2018) todavía bastante nuevo, por lo que tal vez no maneje el JSON no válido de la forma esperada, pero es fácil de instalar en las principales plataformas.

Estoy usando httpie

 $ pip install httpie 

Y puedes usarlo así

  $ http PUT localhost:8001/api/v1/ports/my HTTP/1.1 200 OK Connection: keep-alive Content-Length: 93 Content-Type: application/json Date: Fri, 06 Mar 2015 02:46:41 GMT Server: nginx/1.4.6 (Ubuntu) X-Powered-By: HHVM/3.5.1 { "data": [], "message": "Failed to manage ports in 'my'. Request body is empty", "success": false } 

La versión PHP, si tienes PHP> = 5.4.

 alias prettify_json=php -E '$o = json_decode($argn); print json_encode($o, JSON_PRETTY_PRINT);' echo '{"a":1,"b":2}' | prettify_json