desenv-web-rp.com

Como posso imprimir JSON em um script Shell?

Existe um script (Unix) Shell para formatar JSON em forma legível?

Basicamente, eu quero transformar o seguinte:

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

... em algo como isto:

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

Com o Python 2.6+, você pode apenas fazer:

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

ou, se o JSON estiver em um arquivo, você pode fazer:

python -m json.tool my_json.json

se o JSON for de uma fonte da Internet, como uma API, você poderá usar

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

Por conveniência, em todos esses casos, você pode criar um alias:

alias prettyjson='python -m json.tool'

Para ainda mais conveniência com um pouco mais de digitação para prepará-lo:

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 os casos acima. Você pode colocar isso em .bashrc e ele estará disponível toda vez no Shell. Invoque-o como prettyjson_s '{"foo": "lorem", "bar": "ipsum"}'.

3958
B Bycroft

Você pode usar: jq

É muito simples de usar e funciona muito bem! Ele pode manipular estruturas JSON muito grandes, incluindo fluxos. Você pode encontrar Seus tutoriais aqui .

Aqui está um exemplo:

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

Ou em outras palavras:

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

Eu uso o argumento "space" de JSON.stringify para imprimir em JSON em JavaScript.

Exemplos:

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

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

Da linha de comando Unix com nodejs, especificando json na linha de comando:

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

Retorna:

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

Da linha de comando Unix com Node.js, especificando um nome de arquivo que contenha JSON e usando um recuo de quatro espaços:

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

Usando um tubo:

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

Eu escrevi uma ferramenta que tem um dos melhores formatadores "espaço em branco inteligente" disponíveis. Produz uma saída mais legível e menos detalhada do que a maioria das outras opções aqui.

underscore-cli

Isto é o que "espaço em branco inteligente" se parece:

Eu posso ser um pouco tendencioso, mas é uma ferramenta incrível para imprimir e manipular dados JSON a partir da linha de comando. É super amigável para usar e tem extensa ajuda/documentação de linha de comando. É um canivete suíço que eu uso para 1001 pequenas tarefas diferentes que seriam surpreendentemente irritantes de qualquer outra forma.

Último caso de uso: Chrome, Dev Console, guia Rede, exportar todos como arquivo HAR, "cat site.har | sublinhar selecionar '.url' --outfmt text | grep mydomain"; Agora eu tenho uma lista ordenada cronologicamente de todas as buscas de URL feitas durante o carregamento do site da minha empresa.

Impressão bonita é fácil:

underscore -i data.json print

Mesma coisa:

cat data.json | underscore print

Mesma coisa, mais explícito:

cat data.json | underscore print --outfmt pretty

Esta ferramenta é o meu atual projeto de paixão, por isso, se você tiver alguma solicitação de recurso, há uma boa chance de eu abordá-la.

326
Dave Dopson

Eu costumo apenas fazer:

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

E para recuperar dados selecionados (neste caso, o valor do "teste"):

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

Se os dados JSON estiverem em um arquivo:

python -mjson.tool filename.json

Se você quiser fazer tudo de uma vez, vá com curl na linha de comando usando um token de autenticação:

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

Graças aos ponteiros muito úteis do J.F. Sebastian, aqui está um script ligeiramente melhorado que eu criei:

#!/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 __== "__main__":
    sys.exit(not main(sys.argv))
85
AnC

Se você usa npm e Node.js, você pode fazer npm install -g json e depois canalizar o comando através de json. Faça json -h para obter todas as opções. Também pode extrair campos específicos e colorir a saída com -i.

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

Com o Perl, use o módulo CPAN JSON::XS. Ele instala uma ferramenta de linha de comando json_xs.

Validar:

json_xs -t null < myfile.json

Aplique o arquivo JSON src.json a pretty.json:

< src.json json_xs > pretty.json

Se você não tiver json_xs, tente json_pp. "pp" é para "Perl puro" - a ferramenta é implementada apenas em Perl, sem uma ligação a uma biblioteca C externa (que é o que significa XS, "Sistema de Extensão" da Perl).

68
knb

No * nix, ler de stdin e escrever para stdout funciona melhor:

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

Coloque isso em um arquivo (eu nomeei o meu "prettyJSON" depois de resposta do AnC ) no seu PATH e chmod +x, e você está pronto para ir.

67
Daryl Spitzer

O JSON Ruby Gem é empacotado com um script Shell para enfeitar o JSON:

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

Download de script: Gist.github.com/3738968

64
Paul Horsfall

Não é muito simples com uma maneira nativa com as ferramentas jq .

Por exemplo: 

cat xxx | jq .
63
Olexandr Minzak

UPDATE Estou usando jq agora como sugerido em outra resposta. É extremamente poderoso para filtrar o JSON, mas, na sua forma mais básica, também é uma ótima maneira de imprimir JSON para visualizar.

jsonpp é uma bela impressora de linha de comando JSON bonita.

Do README:

Respostas de serviços da web de impressão bonita como:

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

e deixe os arquivos bonitos no seu disco:

jsonpp data/long_malformed.json

Se você está no Mac OS X, você pode brew install jsonpp. Se não, você pode simplesmente copiar o binário para algum lugar no seu $PATH.

53
jordelver

Tente pjson . Tem cores!

echo '{"json":"obj"} | pjson

Instale-o com pip:

⚡ pip install pjson

E, em seguida, canalize qualquer conteúdo JSON para pjson.

51
Johann Philipp Strathausen

É assim que eu faço:

curl yourUri | json_pp

Ele encurta o código e faz o trabalho.

42
JedatKinports
$ 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: Não é maneira de fazê-lo o.

O mesmo em 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 você correr

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

o Word bem legível torna-se codificado

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

Se o restante de seu pipeline for manipular unicode e você quiser que seu JSON também seja amigável para o ser humano, simplesmente useensure_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 você terá:

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

Eu uso jshon para fazer exatamente o que você está descrevendo. Apenas corra:

echo $COMPACTED_JSON_TEXT | jshon

Você também pode transmitir argumentos para transformar os dados JSON.

39
yardena

Confira Jazor . É um analisador JSON de linha de comando simples escrito em Ruby.

gem install jazor
jazor --help
37
Mike

Ou, com Ruby:

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

Simplesmente canalize a saída para jq ..

Exemplo:

twurl -H ads-api.Twitter.com '.......' | jq .
29
Ackshaey Singh

JSONLint tem uma implementação open-source no github pode ser usado na linha de comando ou incluído em um projeto node.js.

npm install jsonlint -g

e depois

jsonlint -p myfile.json

ou

curl -s "http://api.Twitter.com/1/users/show/user.json" | jsonlint | less
28
Salman A

Bash de baunilha

Um script Bash simples (grep/awk) para impressão JSON bonita, sem instalação de terceiros:

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

Exemplos:

1) Leia arquivo e impressão bonita no console

cat file.json | json_pretty.sh

2) Use com o Bash GIT do Windows de arquivo para arquivo (baseado em UTF8):

cat fileIn.json |sh.exe json_pretty.sh > fileOut.json
23
Evgeny Karpov

Com o Perl, se você instalar o JSON :: PP do CPAN, você receberá o comando json_pp . Roubando o exemplo de B Bycroft você recebe:

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

Vale a pena mencionar que json_pp vem pré-instalado com o Ubuntu 12.04 (pelo menos) e o Debian em /usr/bin/json_pp

19
Philip Durbin

Eu recomendo usar o utilitário de linha de comando json_xs que está incluído no módulo JSON :: XS Perl. JSON :: XS é um módulo Perl para serializar/desserializar JSON, em uma máquina Debian ou Ubuntu você pode instalá-lo assim:

Sudo apt-get install libjson-xs-Perl

Está obviamente também disponível em CPAN .

Para usá-lo para formatar o JSON obtido de um URL, você pode usar curl ou wget como este:

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

ou isto:

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

e para formatar o JSON contido em um arquivo, você pode fazer isso:

$ json_xs < file-full-of.json

Para reformatar como YAML , o que algumas pessoas consideram mais legível do que JSON:

$ json_xs -t yaml < file-full-of.json
18
htaccess
  1. brew install jq
  2. command + | jq 
  3. (exemplo: curl localhost:5000/blocks | jq)
  4. Apreciar!

enter image description here

15
alexanderjsingleton

jj é super-rápido, pode lidar com documentos JSON enormes economicamente, não mexer com números JSON válidos, e é fácil de usar, por ex. 

jj -p # for reading from STDIN

ou

jj -p -i input.json

É (2018) ainda bastante novo, então talvez ele não lide com o JSON inválido da maneira esperada, mas é fácil de instalar nas principais plataformas.

14
peak

Instale as ferramentas yajl com o comando abaixo:

Sudo apt-get install yajl-tools

então,

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

11
Uma sankar pradhan

yajl é muito bom, na minha experiência. Eu uso seu comando json_reformat para belos arquivos .json em vim, colocando a seguinte linha no meu .vimrc:

autocmd FileType json setlocal equalprg=json_reformat
10
Hank Gay

A versão PHP, se você tiver 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
9
svidgen

Use Ruby em uma linha:

echo '{"test":1,"test2":2}' | Ruby -e "require 'json'; puts JSON.pretty_generate(JSON.parse(STDIN.read))"

E você pode definir um alias para isso:

alias to_j="Ruby -e \"require 'json';puts JSON.pretty_generate(JSON.parse(STDIN.read))\""

Então você pode usá-lo mais convenientemente

echo '{"test":1,"test2":2}' | to_j

{
  "test": 1,
  "test2": 2
}

E se você quiser exibir JSON com cor, você pode instalar awesome_print,

gem install awesome_print

então

alias to_j="Ruby -e \"require 'json';require 'awesome_print';ap JSON.parse(STDIN.read)\""

Tente!

echo '{"test":1,"test2":2, "arr":["aa","bb","cc"] }' | to_j

Enter image description here

8
fangxing

bat é um clone cat com realce de sintaxe: https://github.com/sharkdp/bat

Exemplo:

echo '{"bignum":1e1000}' | bat -p -l json

-p será enviado sem cabeçalhos, e -l especificará explicitamente o idioma.

Ele tem coloração e formatação para json, e não tem os problemas observados neste comentário: Como eu posso imprimir um JSON bonito em um script Shell?

8
Grav

Estou usando httpie

$ pip install httpie

E você pode usá-lo assim

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

Eu sei que esta pergunta foi respondida ad nauseam, mas eu queria documentar uma solução Ruby que é melhor do que o comando prettify de Json, a gem colorful_json é bastante boa.

gem install colorful_json
echo '{"foo": "lorem", "bar": "ipsum"}' | cjson
{
  "foo": "lorem",
  "bar": "ipsum"
}
7
Pablo Fernandez heelhook

As soluções do J.F. Sebastian não funcionaram para mim no Ubuntu 8.04.
Aqui está uma versão modificada do Perl que funciona com a antiga biblioteca JSX 1.X:

Perl -0007 -MJSON -ne 'print objToJson(jsonToObj($_, {allow_nonref=>1}), {pretty=>1}), "\n";'
7
pimlottc
echo "{ \"foo\": \"lorem\", \"bar\": \"ipsum\" }"|python -m json.tool

você pode usar este comando simples para alcançar o resultado.

7
Arpit Rathod
$ Sudo apt-get install edit-json
$ prettify_json myfile.json
6
Bryan Larsen

Aqui está como fazer isso com Groovy script.

Crie um script Groovy, digamos "pretty-print"

#!/usr/bin/env groovy

import groovy.json.JsonOutput

System.in.withReader { println JsonOutput.prettyPrint(it.readLine()) }

Torne o script executável:

chmod +x pretty-print

Agora, a partir da linha de comando

echo '{"foo": "lorem", "bar": "ipsum"}' | ./pretty-print
5
numan salati

Existe TidyJSON .

É C #, então talvez você possa compilar com Mono , e trabalhando em * nix. Não há garantias, desculpe.

5
Robert Gould

A ferramenta ydump é uma impressora bonita JSON:

$ ydump my_data.json
{
  "foo": "lorem",
  "bar": "ipsum"
}

Ou você pode canalizar no JSON:

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

Esta é provavelmente a solução mais curta, além de usar a ferramenta jq.

Essa ferramenta faz parte da biblioteca yojson para OCaml e está documentada here .

No Debian e derivados, o pacote libyojson-ocaml-dev contém esta ferramenta. Alternativamente, yojson pode ser instalado via OPAM .

5
josch

Para o Node.js, você também pode usar o módulo "util". Ele usa realce de sintaxe, recuo inteligente, remove aspas das chaves e apenas torna a saída tão bonita quanto possível.

cat file.json | node -e "process.stdin.pipe(new require('stream').Writable({write: chunk =>  {console.log(require('util').inspect(JSON.parse(chunk), {depth: null, colors: true}))}}))"
4
adius

Eu sou o autor de json-liner . É uma ferramenta de linha de comando para transformar o JSON em um formato amigável ao grep. De uma chance.

$ echo '{"a": 1, "b": 2}' | json-liner
/%a 1
/%b 2
$ echo '["foo", "bar", "baz"]' | json-liner
/@0 foo
/@1 bar
/@2 baz
3
Wu Yongzheng

Se você tiver o Node.js instalado, poderá criar um sozinho com uma linha de código. Crie um arquivo bonito:

> vim bonita

#!/usr/bin/env node

console.log(JSON.stringify(JSON.parse(process.argv[2]), null, 2));

Adicione permissão de execução:

> chmod + x bonito

> ./pretty '{"foo": "lorem", "bar": "ipsum"}'

Ou se o seu JSON estiver em um arquivo:

#!/usr/bin/env node

console.log(JSON.stringify(require("./" + process.argv[2]), null, 2));

> ./pretty file.json

3
Nikhil Ranjan

Com JavaScript/NodeJS: dê uma olhada no plug-in vkBeautify.js , que fornece uma impressão bonita para o texto JSON e XML.

Está escrito em JavaScript simples, menos de 1.5KB (minificado) e muito rápido.

3
vadimk

Aqui está o Groovy one-liner:

echo '{"foo": "lorem", "bar": "ipsum"}' | groovy -e 'import groovy.json.*; println JsonOutput.prettyPrint(System.in.text)'
2
Orest Ivasiv

https://github.com/aidanmelen/json_pretty_print

from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import print_function
from __future__ import division

import json
import jsonschema

def _validate(data):
    schema = {"$schema": "http://json-schema.org/draft-04/schema#"}
    try:
        jsonschema.validate(data, schema,
                            format_checker=jsonschema.FormatChecker())
    except jsonschema.exceptions.ValidationError as ve:
        sys.stderr.write("Whoops, the data you provided does not seem to be " \
        "valid JSON.\n{}".format(ve))

def pprint(data, python_obj=False, **kwargs):
    _validate(data)
    kwargs["indent"] = kwargs.get("indent", 4)
    pretty_data = json.dumps(data, **kwargs)
    if python_obj:
        print(pretty_data)
    else:
       repls = (("u'",'"'),
                ("'",'"'),
                ("None",'null'),
                ("True",'true'),
                ("False",'false'))
    print(reduce(lambda a, kv: a.replace(*kv), repls, pretty_data))
2
Aidan Melen
gem install jsonpretty
echo '{"foo": "lorem", "bar": "ipsum"}' | jsonpretty

Este método também "Detecta resposta/cabeçalhos HTTP, imprime-os intocados e pula para O corpo (para uso com 'curl -i')" .

2
lev

Uma solução de uma linha usando o nodejs será semelhante a esta

$ node -e "console.log( JSON.stringify( JSON.parse(require('fs').readFileSync(0) ), 0, 1 ))"

por exemplo:

$ cat test.json | node -e "console.log( JSON.stringify( JSON.parse(require('fs').readFileSync(0) ), 0, 1 ))"
1
harish2704

Você pode usar smk :

echo '{"foo": "lorem", "bar": "ipsum"}' | smk -e"JSON.stringify(JSON.parse(data), null, 4)"

Numa linha

echo '{"foo": "lorem", "bar": "ipsum"}' | npx smk -e"JSON.stringify(JSON.parse(data), null, 4)"
1
Thilina Hasantha

Se você não se incomodar em usar uma ferramenta de terceiros, pode simplesmente encurvar para jsonprettyprint.org . Isto é para o caso em que você não pode instalar pacotes na máquina.

curl -XPOST https://jsonprettyprint.org/api -d '{"user" : 1}'
0
Yada
0
chronos

Meus arquivos JSON não foram analisados ​​por nenhum desses métodos. 

Meu problema foi semelhante a este post JSON de fonte de dados do Google não é válido? .

A resposta para esse post me ajudou a encontrar uma solução. https://stackoverflow.com/a/628634/619760

É considerado um JSON inválido sem as chaves de string.

{id:'name',label:'Name',type:'string'}

devemos ser:

{"id": "name", "label": "Name", "type": "string"}

Este link fornece uma comparação abrangente e agradável de alguns dos diferentes analisadores JSON. http://deron.meranda.us/python/comparing_json_modules/basic

O que me levou a http://deron.meranda.us/python/demjson/ . Eu acho que este analisador é muito mais tolerante a falhas do que muitos outros. 

0
nelaaro

Você pode usar Xidel

O Xidel é uma ferramenta de linha de comando para baixar e extrair dados de páginas HTML/XML ou APIs JSON, usando modelos CSS, XPath 3.0, XQuery 3.0, JSONiq ou padrão. Também pode criar documentos XML/HTML/JSON novos ou transformados.

Xidel pretty-prints por padrão:

$ xidel -s - -e '$json' <<< '{"foo":"lorem","bar":"ipsum"}'
{
  "foo": "lorem",
  "bar": "ipsum"
}

ou:

$ echo '{"foo":"lorem","bar":"ipsum"}' | xidel -s - -e .
{
  "foo": "lorem",
  "bar": "ipsum"
}
0
Reino