web-dev-qa-db-fra.com

Comment puis-je imprimer en JSON JSON dans un script Shell?

Existe-t-il un script (Unix) Shell pour formater JSON sous une forme lisible par l'homme?

En gros, je veux que cela transforme ce qui suit:

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

... dans quelque chose comme ça:

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

Avec Python 2.6+, vous pouvez simplement faire:

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

ou, si le JSON est dans un fichier, vous pouvez faire:

python -m json.tool my_json.json

si le JSON provient d'une source Internet telle qu'une API, vous pouvez utiliser

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

Pour plus de commodité dans tous ces cas, vous pouvez créer un alias:

alias prettyjson='python -m json.tool'

Pour encore plus de commodité avec un peu plus de frappe pour le préparer:

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

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

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

pour tous les cas ci-dessus. Vous pouvez l'insérer dans .bashrc et il sera disponible à chaque fois dans Shell. Invoquez-le comme prettyjson_s '{"foo": "lorem", "bar": "ipsum"}'.

3958
B Bycroft

Vous pouvez utiliser: jq

C'est très simple à utiliser et ça marche très bien! Il peut gérer de très grandes structures JSON, y compris des flux. Vous pouvez trouver Leurs tutoriels ici .

Voici un exemple:

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

Ou en d'autres termes:

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

J'utilise l'argument "space" de JSON.stringify pour imprimer du code JSON en JavaScript.

Exemples:

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

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

A partir de la ligne de commande Unix avec nodejs, en spécifiant JSON sur la ligne de commande:

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

Résultats:

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

A partir de la ligne de commande Unix avec Node.js, spécifiez un nom de fichier contenant JSON et utilisez un retrait de quatre espaces:

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

À l'aide d'un tuyau:

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

J'ai écrit un outil qui possède l'un des meilleurs formateurs "d'espaces intelligents" disponibles. Il produit une sortie plus lisible et moins détaillée que la plupart des autres options présentées ici.

underscore-cli

Voici à quoi ressemble "l'espace vide":

 

Je suis peut-être un peu partial, mais c'est un outil formidable pour imprimer et manipuler des données JSON à partir de la ligne de commande. Il est extrêmement convivial et comprend une aide/documentation complète en ligne de commande. C'est un couteau suisse que j'utilise pour 1001 petites tâches différentes, ce qui serait étonnamment agaçant de le faire autrement.

Dernier cas d'utilisation: Chrome, console de développement, onglet Réseau, tout exporter sous un fichier HAR, "cat site.har | underscore, sélectionnez '.url' --outfmt text | grep mydomain"; J'ai maintenant une liste chronologique de tous les extractions d'URL effectuées lors du chargement du site de mon entreprise.

Une jolie impression est facile:

underscore -i data.json print

Même chose:

cat data.json | underscore print

Même chose, plus explicite:

cat data.json | underscore print --outfmt pretty

Cet outil est mon projet de passion actuel, donc si vous avez des demandes de fonctionnalités, il y a de fortes chances que je les réponde.

326
Dave Dopson

D'habitude je fais juste:

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

Et pour récupérer des données sélectionnées (dans ce cas, la valeur de "test"):

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

Si les données JSON sont dans un fichier:

python -mjson.tool filename.json

Si vous voulez tout faire en une fois, avec curl sur la ligne de commande, utilisez un jeton d'authentification:

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

Merci aux conseils très utiles de J.F. Sebastian, voici un script légèrement amélioré que j'ai créé:

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

Si vous utilisez npm et Node.js, vous pouvez utiliser npm install -g json, puis diriger la commande via json. Faites json -h pour obtenir toutes les options. Il peut également extraire des champs spécifiques et coloriser la sortie avec -i.

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

Avec Perl, utilisez le module CPAN JSON::XS. Il installe un outil en ligne de commande json_xs.

Valider:

json_xs -t null < myfile.json

Confirmez le fichier JSON src.json à pretty.json:

< src.json json_xs > pretty.json

Si vous n'avez pas json_xs, essayez json_pp. "pp" est pour "pur Perl" - l'outil est implémenté uniquement dans Perl, sans liaison à une bibliothèque C externe (ce que XS signifie, "Système d'extension" de Perl).

68
knb

Sur * nix, lire à partir de stdin et écrire sur stdout fonctionne mieux:

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

Mettez ceci dans un fichier (j'ai nommé le mien "prettyJSON" après la réponse de AnC ) dans votre PATH et chmod +x, et vous pourrez continuer.

67
Daryl Spitzer

Le JSON Ruby Gem est fourni avec un script Shell pour personnaliser le JSON:

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

Téléchargement du script: Gist.github.com/3738968

64
Paul Horsfall

Ce n'est pas trop simple avec une manière native avec les outils jq .

Par exemple: 

cat xxx | jq .
63
Olexandr Minzak

UPDATE J'utilise maintenant jq comme suggéré dans une autre réponse. Il est extrêmement puissant pour filtrer le JSON, mais, à la base, aussi un moyen génial d’imprimer de jolis JSON pour la visualisation.

jsonpp est une très belle imprimante JSON en ligne de commande.

Du README:

Jolies réponses du service Web imprimées comme ceci:

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

et rendez beaux les fichiers qui circulent sur votre disque:

jsonpp data/long_malformed.json

Si vous utilisez Mac OS X, vous pouvez brew install jsonpp. Sinon, vous pouvez simplement copier le fichier binaire quelque part dans votre $PATH.

53
jordelver

Essayez pjson . Il a des couleurs!

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

Installez-le avec pip:

⚡ pip install pjson

Et puis dirigez tout contenu JSON vers pjson.

C'est comme ça que je le fais:

curl yourUri | json_pp

Cela raccourcit le code et fait le travail.

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

NOTE: Ce n'est pas le manière de le faire.

La même chose en Perl:

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

Note 2: Si vous exécutez

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

le mot bien lisible devient\u codé

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

Si le reste de votre pipeline gère gracieusement Unicode et que vous souhaitez que votre JSON soit également convivial, utilisez simplement utilisezensure_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)'

et vous aurez:

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

J'utilise jshon pour faire exactement ce que vous décrivez. Il suffit de courir:

echo $COMPACTED_JSON_TEXT | jshon

Vous pouvez également passer des arguments pour transformer les données JSON.

39
yardena

Départ Jazor . C'est un simple analyseur JSON en ligne de commande écrit en Ruby.

gem install jazor
jazor --help
37
Mike

Ou, avec Ruby:

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

Dirigez simplement la sortie vers jq ..

Exemple:

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

JSONLint a une implémentation open source sur github peut être utilisé en ligne de commande ou inclus dans un projet node.js.

npm install jsonlint -g

et alors

jsonlint -p myfile.json

ou

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

Vanilla Bash

Un simple script Bash (grep/awk) pour une jolie impression JSON, sans installation tierce:

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

Exemples:

1) Lire le fichier et imprimer en console

cat file.json | json_pretty.sh

2) Utilisez avec les fenêtres GIT Bash de fichier à fichier (basé sur UTF8):

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

Pygmentize

Je combine json.tool de Python avec pygmentize:

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

Il y a quelques alternatives à segmenter qui sont listées dans cette réponse .

Voici une démo en direct:

 Demo

23
Shubham Chaudhary

Avec Perl, si vous installez JSON :: PP à partir de CPAN, vous obtiendrez la commande json_pp . Voler le exemple de B Bycroft vous obtenez:

[pdurbin@beamish ~]$ echo '{"foo": "lorem", "bar": "ipsum"}' | json_pp
{
   "bar" : "ipsum",
   "foo" : "lorem"
}

Il est à noter que json_pp est livré préinstallé avec Ubuntu 12.04 (au moins) et Debian dans /usr/bin/json_pp

19
Philip Durbin

Je recommande d'utiliser l'utilitaire de ligne de commande json_xs, inclus dans le module JSON :: XS Perl. JSON :: XS est un module Perl pour la sérialisation/désérialisation de JSON. Sur une machine Debian ou Ubuntu, vous pouvez l'installer comme ceci:

Sudo apt-get install libjson-xs-Perl

Il est évidemment également disponible sur CPAN .

Pour l'utiliser au format JSON obtenu à partir d'une URL, vous pouvez utiliser curl ou wget comme ceci:

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

ou ca:

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

et pour formater le fichier JSON contenu dans un fichier, procédez comme suit:

$ json_xs < file-full-of.json

Pour reformater en tant que YAML , que certaines personnes considèrent plus lisible par l'homme que JSON:

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

 enter image description here

15
alexanderjsingleton

jj est ultra-rapide, peut gérer des documents JSON ginormeux de manière économique, ne pas jouer avec les numéros JSON valides et est facile à utiliser, par exemple. 

jj -p # for reading from STDIN

ou

jj -p -i input.json

Il est (2018) encore relativement récent, il ne gérera peut-être pas un JSON non valide comme prévu, mais il est facile à installer sur les principales plates-formes.

14
peak

Installez yajl-tools avec la commande ci-dessous:

Sudo apt-get install yajl-tools

puis,

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

11
Uma sankar pradhan

yajl est très gentil, d'après mon expérience. J'utilise sa commande json_reformat pour imprimer des fichiers .json dans vim en mettant la ligne suivante dans mon .vimrc:

autocmd FileType json setlocal equalprg=json_reformat
10
Hank Gay

La version PHP, si vous avez 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

Utilisez Ruby sur une ligne:

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

Et vous pouvez définir un alias pour cela:

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

Ensuite, vous pouvez l'utiliser plus facilement

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

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

Et si vous voulez afficher JSON en couleur, vous pouvez installer awesome_print,

gem install awesome_print

puis

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

Essayez le!

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

 Enter image description here

8
fangxing

bat est un clone cat avec une coloration syntaxique: https://github.com/sharkdp/bat

Exemple:

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

-p sera affiché sans en-tête, et -l spécifiera explicitement la langue.

Il a la coloration et la mise en forme pour JSON, et not a les problèmes notés dans ce commentaire: Comment puis-je imprimer en JSON dans un script Shell?

8
Grav

J'utilise httpie

$ pip install httpie

Et vous pouvez l'utiliser comme ça

 $ 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

Je sais que cette question a été répondue ad nauseam, mais je voulais documenter une solution Ruby qui est meilleure que la commande prettify de Json, la gem colorful_json est relativement bonne.

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

Les solutions de J.F. Sebastian ne fonctionnaient pas pour moi dans Ubuntu 8.04.
Voici une version modifiée de Perl qui fonctionne avec l'ancienne bibliothèque JSON 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

vous pouvez utiliser cette commande simple pour obtenir le résultat.

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

Voici comment faire avec Groovy script.

Créez un script Groovy, disons "joli imprimé"

#!/usr/bin/env groovy

import groovy.json.JsonOutput

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

Rendre le script exécutable:

chmod +x pretty-print

Maintenant, à partir de la ligne de commande,

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

Il y a TidyJSON .

C'est C #, alors vous pouvez peut-être le compiler avec Mono , et travailler sur * nix. Aucune garantie cependant, désolé.

5
Robert Gould

L'outil ydump est une jolie imprimante JSON:

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

Ou vous pouvez diriger dans le JSON:

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

C’est probablement la solution la plus courte en dehors de l’utilisation de l’outil jq.

Cet outil fait partie de la bibliothèque yojson pour OCaml et est documenté ici .

Sur Debian et ses dérivés, le paquetage libyojson-ocaml-dev contient cet outil. Vous pouvez également installer yojson via OPAM .

5
josch

Pour Node.js, vous pouvez également utiliser le module "util". Il utilise la mise en évidence de la syntaxe, l'indentation intelligente, supprime les guillemets des clés et rend la sortie aussi jolie que possible.

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

Je suis l'auteur de json-liner . Il s'agit d'un outil de ligne de commande permettant de convertir JSON en un format convivial pour Grep. Essaie.

$ 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

Si vous avez installé Node.js, vous pouvez en créer un vous-même avec une ligne de code. Créez un fichier joli:

> vim pretty

#!/usr/bin/env node

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

Ajouter une autorisation d'exécution:

> chmod + x jolie

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

Ou si votre JSON est dans un fichier:

#!/usr/bin/env node

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

> ./pretty file.json

3
Nikhil Ranjan

Avec JavaScript/NodeJS: jetez un oeil au plugin vkBeautify.js , qui fournit une jolie impression à la fois pour le texte JSON et XML.

Il est écrit en JavaScript, moins de 1,5 Ko (minifié) et très rapide.

3
vadimk

Voici 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

Cette méthode utilise également "Détecte les en-têtes/réponses HTTP, les affiche telles quelles et affiche le corps (À utiliser avec` curl -i ') " .

2
lev

Une solution à une ligne utilisant nodejs ressemblera à ceci

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

pour par exemple:

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

Vous pouvez utiliser smk :

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

Sur une ligne

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

Si cela ne vous dérange pas d’utiliser un outil tiers, vous pouvez simplement vous courber vers jsonprettyprint.org . Ceci est le cas où vous ne pouvez pas installer de paquet sur la machine.

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

Mes fichiers JSON n'ont été analysés par aucune de ces méthodes. 

Mon problème était similaire à celui de cet article Google Data Source JSON n'est pas valide? .

La réponse à cet article m'a aidé à trouver une solution. https://stackoverflow.com/a/628634/619760

Il est considéré comme un JSON non valide sans les clés de chaîne.

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

doit être:

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

Ce lien offre une comparaison complète et agréable de certains des différents analyseurs JSON. http://deron.meranda.us/python/comparing_json_modules/basic

Ce qui m'a amené à http://deron.meranda.us/python/demjson/ . Je pense que cet analyseur est beaucoup plus tolérant aux fautes que beaucoup d’autres. 

0
nelaaro

Vous pouvez utiliser Xidel

Xidel est un outil de ligne de commande permettant de télécharger et d'extraire des données de pages HTML/XML ou d'API JSON, à l'aide de CSS, XPath 3.0, XQuery 3.0, JSONiq ou de modèles. Il peut également créer des documents XML/HTML/JSON nouveaux ou transformés.

Xidel pretty-prints par défaut:

$ 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