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




read json in shell script (20)

¿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:


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:

[[email protected] ~]$ 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 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

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.


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



O, con Ruby:

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

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

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.


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


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 .





pretty-print