Come posso stampare abbastanza JSON in uno script di shell(Unix)?




command-line format (24)

Esiste uno script di shell (Unix) per formattare JSON in forma leggibile?

Fondamentalmente, voglio che trasformi il seguente:

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

... in qualcosa di simile:

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

JSONLint ha JSONLint open-source su github può essere usato sulla riga di comando o incluso in un progetto node.js.

npm install jsonlint -g

e poi

jsonlint -p myfile.json

o

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

Grazie agli indicatori molto utili di JF Sebastian, ecco una sceneggiatura leggermente migliorata che ho trovato:

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

Con Perl, usa il modulo CPAN JSON::XS . Installa uno strumento da riga di comando json_xs .

Convalidare:

json_xs -t null < myfile.json

Prelevi il file JSON src.json a pretty.json :

< src.json json_xs > pretty.json

Se non hai json_xs , prova json_pp . "pp" è per "puro perl" - lo strumento è implementato solo in Perl, senza un binding a una libreria C esterna (che è ciò che XS rappresenta, "Extension System" di Perl).


Con Perl, se installi JSON::PP da CPAN otterrai il comando json_pp . Rubando l' example di B Bycroft ottieni:

[[email protected] ~]$ echo '{"foo": "lorem", "bar": "ipsum"}' | json_pp
{
   "bar" : "ipsum",
   "foo" : "lorem"
}

Vale la pena ricordare che json_pp viene preinstallato con Ubuntu 12.04 (almeno) e Debian in /usr/bin/json_pp


La versione PHP, se hai 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

Vanilla Bash

Un semplice script Bash ( grep / awk ) per una bella stampa JSON, senza installazione di terze parti:

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

Esempi:

1) Leggi file e bella stampa in console

cat file.json | json_pretty.sh

2) Utilizzare con Windows GIT Bash da file a file (basato su UTF8):

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

Prova pjson . Ha colori!

Installalo con pip :

⚡ pip install pjson

E poi reindirizzare qualsiasi contenuto JSON su pjson .


Se si utilizza npm e Node.js, è possibile eseguire npm install -g json e quindi npm install -g json il comando tramite json . json -h per avere tutte le opzioni. Può anche estrarre campi specifici e colorare l'output con -i .

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

$ 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: non è il modo di farlo.

Lo stesso in Perl:

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

Nota 2: se corri

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 parola ben leggibile diventa \ u codificata

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

Se il resto della tua pipeline gestirà con garbo l'unicode e vorresti che il tuo JSON sia anche umano, use semplicemente 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)'

e otterrai:

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

Raccomando di usare l'utilità della riga di comando json_xs che è inclusa nel modulo perl JSON :: XS. JSON :: XS è un modulo Perl per serializzare / deserializzare JSON, su una macchina Debian o Ubuntu puoi installarlo in questo modo:

sudo apt-get install libjson-xs-perl

Ovviamente è disponibile anche su CPAN .

Per usarlo per formattare JSON ottenuto da un URL puoi usare curl o wget in questo modo:

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

o questo:

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

e per formattare JSON contenuto in un file puoi farlo:

$ json_xs < file-full-of.json

Per riformattare come YAML , che alcune persone considerano più umanamente leggibile di JSON:

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

yajl è molto carino, secondo la mia esperienza. Io uso il suo comando json_reformat per stampare abbastanza .json file in vim inserendo la seguente riga nel mio .vimrc :

autocmd FileType json setlocal equalprg=json_reformat

Installa yajl-tools con il comando seguente:

sudo apt-get install yajl-tools

poi,

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


Io uso jshon per fare esattamente quello che stai descrivendo. Corri:

echo $COMPACTED_JSON_TEXT | jshon

È anche possibile passare argomenti per trasformare i dati JSON.


Con Python 2.6+ puoi semplicemente:

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

oppure, se il JSON è in un file, puoi fare:

python -m json.tool my_json.json

se il JSON proviene da una fonte internet come un'API, puoi usare

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

Per comodità in tutti questi casi puoi fare un alias:

alias prettyjson='python -m json.tool'

Per ancora più comodità con un po 'più di digitazione per averlo pronto:

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

prettyjson_f() {
    python -m json.tool "$1"
}

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

per tutti i casi di cui sopra. Puoi metterlo in .bashrc e sarà disponibile ogni volta nella shell. Richiamalo come prettyjson_s '{"foo": "lorem", "bar": "ipsum"}' .


Uso l'argomento "spazio" di JSON.stringify per JSON pretty-print in JavaScript.

Esempi:

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

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

Dalla riga di comando Unix con nodejs, specificando json sulla riga di comando:

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

Ritorna:

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

Dalla riga di comando Unix con Node.js, specificando un nome file che contiene JSON e utilizzando un rientro di quattro spazi:

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

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

Su * nix, la lettura da stdin e la scrittura su stdout funzionano meglio:

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

Metti questo in un file (ho chiamato il mio "prettyJSON" dopo la risposta di AnC ) nel tuo PATH e chmod +x it, e sei a posto.


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


JSON Ruby Gem è fornito in bundle con uno script di shell per migliorare JSON:

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

Download di script: gist.github.com/3738968


AGGIORNAMENTO Sto usando jq ora come suggerito in un'altra risposta. È estremamente potente nel filtrare JSON, ma, nel suo modo più semplice, è anche un modo fantastico per stampare in modo semplice JSON per la visualizzazione.

jsonpp è una bella stampante JSON piuttosto bella da riga di comando.

Dal README:

Le risposte al servizio web di stampa sono piuttosto simili:

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

e rendi belli i file che girano sul tuo disco:

jsonpp data/long_malformed.json

Se utilizzi Mac OS X, puoi brew install jsonpp . In caso contrario, puoi semplicemente copiare il file binario in qualche punto del tuo $PATH .


Sto usando httpie

$ pip install httpie

E puoi usarlo in questo modo

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

Ecco come lo faccio:

curl yourUri | json_pp

Riduce il codice e porta a termine il lavoro.


Jazor un'occhiata a Jazor . È un semplice parser JSON a riga di comando scritto in Ruby.

gem install jazor
jazor --help

Oppure, con Ruby:

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

Non è troppo semplice con un modo nativo con gli strumenti jq .

Per esempio:

cat xxx | jq .




pretty-print