script read parse from example data json unix command-line format pretty-print

json - read - jq linux



¿Cómo puedo realizar una impresión bonita de JSON en un script de shell(Unix)? (30)

¿Hay un script de shell (Unix) para formatear JSON en forma legible para el usuario?

Básicamente, quiero que transforme lo siguiente:

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

... en algo como esto:

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


Golpe de vainilla

Una secuencia de comandos Bash simple ( grep / awk ) para impresión JSON bonita, 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 impresión bonita en consola.

cat file.json | json_pretty.sh

2) Use con el GIT Bash de Windows de un archivo a otro (basado en UTF8):

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


Pygementar

Combino json.tool de Python con pygmentize:

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

Hay algunas alternativas para hacer un juicio crítico que se enumeran en mi respuesta .

Aquí hay una demostración en vivo:


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


Así es como lo hago:

curl yourUri | json_pp

Acorta el código y hace el trabajo.


Con Perl, si instala JSON::PP desde CPAN obtendrá el comando json_pp . Robando el example 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


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

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

< src.json json_xs > pretty.json

Si no tiene json_xs , intente 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, "Sistema de extensión" de Perl).


Con Python 2.6+ simplemente puedes hacer:

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 puedes hacer un alias:

alias prettyjson=''python -m json.tool''

Para aún más comodidad con un poco más de escritura para prepararlo:

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 que esté en shell. prettyjson_s ''{"foo": "lorem", "bar": "ipsum"}'' como prettyjson_s ''{"foo": "lorem", "bar": "ipsum"}'' .


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

gem install jazor jazor --help


El JSON Ruby Gem se incluye con un script de shell para pretender JSON:

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

Descarga de script: gist.github.com/3738968


En * nix, leer desde stdin y escribir a 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)

Ponga esto en un archivo (nombré el mío "prettyJSON" después de la respuesta de AnC ) en su PATH y chmod +x it, y listo.


Escribí una herramienta que tiene uno de los mejores formateadores de "espacios en blanco inteligentes" disponibles. Produce una salida más legible y menos detallada que la mayoría de las otras opciones aquí.

underscore-cli

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

Puede que esté un poco sesgado, pero es una herramienta increíble para imprimir y manipular datos JSON desde la línea de comandos. Es muy fácil de usar y tiene una amplia ayuda / documentación en línea de comandos. Es una navaja suiza que utilizo para 1001 tareas pequeñas diferentes que sería sorprendentemente molesto hacer de otra manera.

Último caso de uso: Chrome, consola de desarrollo, pestaña de red, exportar todo como archivo HAR, "cat site.har | subrayado seleccionar ''.url'' --outfmt text | grep mydomain"; ahora tengo una lista ordenada cronológicamente de todas las recuperaciones 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 actual de pasión, por lo que si tiene alguna solicitud de características, es muy probable que las aborde.


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 }


Gracias a los consejos muy útiles de JF Sebastian, he aquí 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))


Instale yajl-tools con el siguiente comando:

sudo apt-get install yajl-tools

entonces,

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


La versión de PHP, si tiene 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



O, con Ruby:

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


Pruebe pjson . ¡Tiene colores!

Instalalo con pip :

⚡ pip install pjson

Y luego canaliza cualquier contenido JSON a pjson .


Puedes usar: jq

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

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" }


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 de 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, puedes usar curl o wget así:

$ 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 puedes hacer esto:

$ json_xs < file-full-of.json

Para reformatear como YAML , lo que algunas personas consideran más legible para las personas que JSON:

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


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 la salida con -i .

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


Simplemente canalice la salida a jq . .

Ejemplo:

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


Uso jshon para hacer exactamente lo que estás describiendo. Solo corre:

echo $COMPACTED_JSON_TEXT | jshon

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


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 comandos con un token de autenticación:

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


Utilizo el argumento "espacio" de JSON.stringify para imprimir 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 comandos:

$ 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, especifique un nombre de archivo que contenga JSON y use una 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 pipa:

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));/ });/ "



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

autocmd FileType json setlocal equalprg=json_reformat


jj es súper rápido, puede manejar documentos JSON gigantescos económicamente, no se mete con 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 JSON no válido de la forma que espera, pero es fácil de instalar en las plataformas principales.


ACTUALIZACIÓN Estoy usando jq ahora como se sugiere en otra respuesta. Es extremadamente poderoso para filtrar JSON, pero, en su forma más básica, también es una forma impresionante de imprimir JSON para ver.

jsonpp es una muy bonita línea de comandos de la impresora JSON.

Desde el README:

Respuestas bonitas del servicio web de impresión así:

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

y embellece los archivos que se ejecutan en tu disco:

jsonpp data/long_malformed.json

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


$ 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 manera 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 bien legible se convierte en / u codificada

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

Si el resto de su canalización manejará con gracia unicode y le gustaría que su JSON también sea amigable para el ser humano, 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á:

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