unix jq - Comment puis-je imprimer de belles couleurs JSON dans un script shell?




bash format (25)

C'est comme ça que je le fais:

gem install jazor
jazor --help

Cela raccourcit le code et fait le travail.

Existe-t-il un script shell (Unix) 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"
}

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.


La version de 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

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

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

curl yourUri | json_pp

Ce n'est pas trop simple avec une méthode native avec les outils jq .

Par exemple:

cat xxx | jq .

$ 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 la façon 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 courez

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 code JSON soit également convivial, use simplement 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)'

et vous aurez:

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

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, exportation sous forme de 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.


Pygmentize

Je combine json.tool de Python avec pygmentize:

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

Il existe certaines alternatives à segmenter qui sont énumérées dans ma réponse .

Voici une démo en direct:


JSONLint a une implémentation open-source sur github qui peut être utilisée en ligne de commande ou incluse 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

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" d'après la réponse de AnC ) dans votre PATH et chmod +x it, et vous voilà prêt à partir.


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

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

Si vous utilisez npm et Node.js, vous pouvez npm install -g json , puis diriger la commande via json . Ne 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

Merci aux astuces très utiles de JF 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 __name__ == "__main__":
    sys.exit(not main(sys.argv))

J'utilise l'argument "space" de JSON.stringify pour JSON.stringify de jolies impressions 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));\
 });\
"

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
 }

Installez yajl-tools avec la commande ci-dessous:

sudo apt-get install yajl-tools

puis,

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


jj est ultra-rapide, peut gérer des documents JSON géniaux de manière économique, ne gêne pas 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 assez récent, il ne gérera peut-être pas le JSON invalide comme prévu, mais il est facile à installer sur les principales plates-formes.


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

Valider:

json_xs -t null < myfile.json

Confirmez le fichier JSON src.json en 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).


Avec Perl, si vous installez JSON::PP partir de CPAN, vous obtiendrez la commande json_pp . En volant l' example de B Bycroft, vous obtenez:

[[email protected] ~]$ 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


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


Essayez pjson . Il a des couleurs!

Installez-le avec pip :

⚡ pip install pjson

Et puis dirigez n'importe quel contenu JSON vers pjson .


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

Je recommande d'utiliser l'utilitaire de ligne de commande json_xs, inclus dans le module perl JSON :: XS. 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

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

$ json_xs < file-full-of.json

Pour reformater en YAML , ce que certaines personnes considèrent plus lisible que JSON:

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

J'ai trouvé ce brillant post sur la redirection: Tout sur les redirections

Redirige la sortie standard et l'erreur standard vers un fichier

$ commande &> fichier

Ce one-liner utilise l'opérateur &> pour rediriger les deux flux de sortie - stdout et stderr - de la commande au fichier. C'est le raccourci de bash pour rediriger rapidement les deux flux vers la même destination.

Voici à quoi ressemble la table des descripteurs de fichiers après que bash ait redirigé les deux flux:

Comme vous pouvez le voir, stdout et stderr pointent maintenant vers un fichier. Tout ce qui est écrit dans stdout et stderr est écrit dans un fichier.

Il existe plusieurs façons de rediriger les deux flux vers la même destination. Vous pouvez rediriger chaque flux les uns après les autres:

$ command> fichier 2> & 1

C'est un moyen beaucoup plus commun de rediriger les deux flux vers un fichier. La première sortie stdout est redirigée vers un fichier, puis stderr est dupliqué pour être identique à stdout. Donc les deux flux finissent par pointer vers le fichier.

Lorsque bash voit plusieurs redirections, il les traite de gauche à droite. Passons en revue les étapes et voyons comment cela se passe. Avant d'exécuter des commandes, la table des descripteurs de fichiers de bash ressemble à ceci:

Maintenant, bash traite le premier fichier de redirection. Nous l'avons vu auparavant et cela fait stdout pointer vers le fichier:

Le prochain bash voit la deuxième redirection 2> & 1. Nous n'avons pas vu cette redirection auparavant. Celui-ci duplique le descripteur de fichier 2 pour qu'il soit une copie du descripteur de fichier 1 et nous obtenons:

Les deux flux ont été redirigés vers le fichier.

Cependant faites attention ici! L'écriture:

commande> fichier 2> & 1

N'est-ce pas la même chose que d'écrire:

$ command 2> & 1> fichier

L'ordre des redirections est important dans bash! Cette commande redirige uniquement la sortie standard vers le fichier. Le stderr sera toujours imprimer sur le terminal. Pour comprendre pourquoi cela se produit, répétons les étapes. Donc, avant d'exécuter la commande, la table des descripteurs de fichiers ressemble à ceci:

Maintenant, bash traite les redirections de gauche à droite. Il voit d'abord 2> & 1 donc il duplique stderr à stdout. La table des descripteurs de fichiers devient:

Maintenant, bash voit le deuxième fichier de redirection> et redirige stdout vers le fichier:

Voyez-vous ce qui se passe ici? Stdout pointe maintenant vers le fichier mais le stderr pointe toujours vers le terminal! Tout ce qui est écrit sur stderr est imprimé à l'écran! Soyez donc très, très prudent avec l'ordre des redirections!

Notez également que dans bash, écrire ceci:

$ commande &> fichier

Est-ce exactement la même chose que:

Commande $> & fichier





json unix command-line format pretty-print