Como posso imprimir JSON em um script de shell (Unix)?

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

Basicamente, quero transformar o seguinte:

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

… em algo como isto:

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

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 é de uma fonte da Internet, como uma API, você pode 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 comodidade 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 no .bashrc e ele estará disponível toda vez no shell. Invoque-o como prettyjson_s '{"foo": "lorem", "bar": "ipsum"}' .

Você pode usar: jq

É muito simples de usar e funciona muito bem! Ele pode manipular estruturas JSON muito grandes, incluindo streams. 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" } 

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

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.

sublinhado-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 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 | sublinhado selecionar ‘.url’ –outfmt text | grep mydomain”; agora tenho uma lista ordenada cronologicamente de todas as pesquisas 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 projeto atual de paixão, por isso, se você tiver alguma solicitação de recurso, há uma boa chance de eu abordá-la.

Eu costumo apenas fazer:

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

E para recuperar dados selecionados (neste caso, o valor de “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 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 

Graças aos pointers muito úteis de JF 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 __name__ == "__main__": sys.exit(not main(sys.argv)) 

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” após a resposta do AnC ) no seu PATH e chmod +x , e você está pronto para ir.

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 

Prettify o arquivo JSON src.json para pretty.json :

 < src.json json_xs > pretty.json 

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

Se você usar o npm e o Node.js, você pode fazer o npm install -g json e depois canalizar o comando através do 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 

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

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

Download de script: gist.github.com/3738968

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

Por exemplo:

 cat xxx | jq . 

ATUALIZAÇÃO Estou usando o 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 a visualização.

jsonpp é uma bela linha de comando JSON pretty printer.

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 .

Tente pjson . Tem colors!

echo '{

Instale-o com pip :

⚡ pip install pjson

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

 $ 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 é a maneira de fazer isso.

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

a palavra bem legível se torna codificada \ u

 { "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, simplesmente 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)' 

e você terá:

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

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.

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

 gem install jazor jazor --help 

Ou, com Ruby:

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

É assim que eu faço:

 curl yourUri | json_pp 

Ele encurta o código e faz o trabalho.

Simplesmente canalize a saída para jq . .

Exemplo:

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

JSONLint tem uma implementação de código aberto no github que pode ser usada na linha de comando ou incluída 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 

Pygngize

Eu combino o json.tool do Python com pygentize:

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

Existem algumas alternativas para pygmentize que estão listadas na minha resposta .

Aqui está uma demonstração ao vivo:

Demonstração

Eu recomendo usar o utilitário de linha de comando json_xs que está incluído no módulo perl JSON :: XS. 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 no CPAN .

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

 $ 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 , que algumas pessoas consideram mais legível do que JSON:

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

Bash de baunilha

Um simples script Bash ( grep / awk ) para impressão JSON, 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 

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

 [pdurbin@beamish ~]$ 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 Debian em /usr/bin/json_pp

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

insira a descrição da imagem aqui

Instale o yajl-tools com o comando abaixo:

sudo apt-get install yajl-tools

então,

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

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

 autocmd FileType json setlocal equalprg=json_reformat 

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 exemplo

 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.

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 } 

A versão do 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