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

2500


origen


Respuestas:


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. Puedes poner esto en .bashrc y estará disponible todo el tiempo en shell. Invocarlo como prettyjson_s '{"foo": "lorem", "bar": "ipsum"}'.


3734



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

687



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

358



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 navaja 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.


321



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 quieres 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

168



Gracias a los consejos muy útiles de J.F. Sebastian, aquí hay un script ligeramente mejorado que se me ocurrió:

#!/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))

82



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 Congreso Nacional Africanorespuesta de) en su RUTA y chmod +x y eres bueno para ir.


66