Wie drucke ich eine JSON-Datei?

1059

Ich habe eine JSON-Datei, die ein Chaos ist, das ich hübsch drucken möchte. Was ist der einfachste Weg, dies in Python zu tun? Ich weiß, dass PrettyPrint ein "Objekt" nimmt, von dem ich denke, dass es eine Datei sein kann, aber ich weiß nicht, wie ich eine Datei übergeben soll - nur die Verwendung des Dateinamens funktioniert nicht.

Colleen
quelle
9
Versuchen Sie, den JSON mit json.loads()dem resultierenden Wörterbuch zu analysieren und hübsch auszudrucken. Oder springen Sie einfach zum Abschnitt Pretty Printing in der Python- Dokumentation fürjson .
Blender
1
@Blender, wenn du eine Antwort postest, gebe ich dir Anerkennung ... dies wird möglicherweise als Duplikat geschlossen, da die Lösung dieselbe ist, aber die Frage anders ist, also vielleicht auch nicht.
Colleen
18
warum nicht <your_file.js python -mjson.toolwie in @ eds Link?
JFS
11
Ich denke nicht, dass es doppelt vorhanden ist, da das hübsche Drucken über die Befehlszeile nicht dasselbe ist wie das programmgesteuerte hübsche Drucken aus Python. Abstimmung zur Wiedereröffnung.
Vitaut

Antworten:

1660

Das jsonModul implementiert bereits einige grundlegende hübsche Drucke mit dem indentParameter:

>>> import json
>>>
>>> your_json = '["foo", {"bar":["baz", null, 1.0, 2]}]'
>>> parsed = json.loads(your_json)
>>> print(json.dumps(parsed, indent=4, sort_keys=True))
[
    "foo", 
    {
        "bar": [
            "baz", 
            null, 
            1.0, 
            2
        ]
    }
]

Verwenden Sie zum Parsen einer Datei Folgendes json.load():

with open('filename.txt', 'r') as handle:
    parsed = json.load(handle)
Mixer
quelle
143
Für einfaches hübsches Drucken funktioniert dies auch ohne explizites Parsen:print json.dumps(your_json_string, indent=4)
Peterino
1
Was macht der Einzug?
Timbram
8
@ Timbram: Es ist die Anzahl der Leerzeichen, um die eingerückt werden soll.
Blender
9
Ohne den Einzug erhalten Sie nur eine einzige Zeile hässlichen Textes, weshalb ich hierher gekommen bin.
krs013
6
@ Peterino Ich musste zuerst json string analysieren: print(json.dumps(json.loads(your_json_string), indent=2))ansonsten zeigte es mir nur einen entkommenen String
vladkras
310

Sie können dies in der Befehlszeile tun:

python3 -m json.tool some.json

(Wie bereits in den Kommentaren zur Frage erwähnt, danke an @Kai Petzke für den Python3-Vorschlag).

Eigentlich ist Python nicht mein Lieblingswerkzeug, wenn es um die Verarbeitung von JSON in der Befehlszeile geht. Für einfaches hübsches Drucken ist es in Ordnung, aber wenn Sie das JSON manipulieren möchten, kann es zu kompliziert werden. Sie müssten bald eine separate Skriptdatei schreiben. Sie könnten Karten erhalten, deren Schlüssel u "some-key" (Python-Unicode) sind, was die Auswahl von Feldern erschwert und nicht wirklich in Richtung hübsch geht -Drucken.

Sie können auch jq verwenden :

jq . some.json

und Sie erhalten Farben als Bonus (und viel einfachere Erweiterbarkeit).

Nachtrag: In den Kommentaren gibt es einige Verwirrung über die Verwendung von jq zum Verarbeiten großer JSON-Dateien einerseits und über ein sehr großes jq-Programm andererseits. Für das hübsche Drucken einer Datei, die aus einer einzelnen großen JSON-Entität besteht, ist die praktische Einschränkung RAM. Für das hübsche Drucken einer 2-GB-Datei, die aus einem einzelnen Array realer Daten besteht, betrug die für das hübsche Drucken erforderliche "maximale residente Satzgröße" 5 GB (unabhängig davon, ob jq 1.5 oder 1.6 verwendet wird). Beachten Sie auch, dass jq innerhalb von Python nach verwendet werden kann pip install jq.

Gismo Ranas
quelle
4
JQ ist großartig, aber es gibt ein maximales Limit, so dass es für große Dateien unbrauchbar ist. (dh sprengt die Verarbeitung einer 1,15-MB-Datei) github.com/stedolan/jq/issues/1041
Chris McKee
3
Ja, Mann, auf jeden Fall, wenn Sie JQ-Filter mit mehr als 10K Codezeilen schreiben, versuchen Sie wahrscheinlich, mit dem Fahrrad zum Mars zu fahren.
Gismo Ranas
2
lol: D @ gismo-ranas Die an eine Datei weitergeleitete Version json.tool funktioniert bei großen Dateien wirklich sehr gut. und ist dumm schnell. Ich mag JQ, aber das Formatieren von Dingen, die über eine kleine Nutzlast hinausgehen (was in den meisten Texteditoren möglich ist), ist unerreichbar :) Zufällige Ergänzung: json-generator.com ist ein nützliches Tool zum Erstellen von Testdaten
Chris McKee
5
oder einfach:jq '' < some.json
fatal_error
2
Eigentlich empfehle ich dringend die Verwendung python3 -m json.tool <IN >OUT, da hierdurch die ursprüngliche Reihenfolge der Felder in JSON-Dikten beibehalten wird. Der Python-Interpreter Version 2 sortiert die Felder in alphabetisch aufsteigender Reihenfolge, was häufig nicht Ihren Wünschen entspricht.
Kai Petzke
55

Sie können den integrierten Moduldruck (https://docs.python.org/3.6/library/pprint.html) verwenden .

So können Sie die Datei mit JSON-Daten lesen und ausdrucken.

import json
import pprint

json_data = None
with open('filename.txt', 'r') as f:
    data = f.read()
    json_data = json.loads(data)

pprint.pprint(json_data)
ikreb
quelle
4
Das Problem dabei ist, dass pprint einfache und doppelte Anführungszeichen austauschbar verwendet, json jedoch nur doppelte Anführungszeichen benötigt, sodass Ihr gedruckter json möglicherweise nicht mehr als gültiger json analysiert wird.
Drevicko
1
Ja, aber es wird nur eine JSON-Datei ausgegeben. Die Ausgabe nicht zu nehmen und sie erneut in eine Datei zu schreiben.
Ikreb
52

Pygementize + Python json.tool = Hübscher Druck mit Syntaxhervorhebung

Pygementize ist ein Killer-Tool. Sieh dir das an.

Ich kombiniere python json.tool mit pygementize

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

Unter dem obigen Link finden Sie Anweisungen zur Installation von pygementize.

Eine Demo davon finden Sie im Bild unten:

Demo

Shubham Chaudhary
quelle
1
In Ihrem Beispiel -gfunktioniert das nicht wirklich;) Da die Eingabe von stdin stammt, kann pygementize keine guten Vermutungen anstellen. Sie müssen Lexer explizit angeben:echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Denis The Menace
1
@DenisTheMenace Es hat 2015 funktioniert, als ich dieses Beispielbild erstellt habe. Es scheint jetzt auch auf meinem System nicht zu funktionieren.
Shubham Chaudhary
36

Verwenden Sie diese Funktion und schwitzen Sie nicht, wenn Sie sich daran erinnern müssen, ob es sich bei Ihrem JSON um einen stroder einen anderen handelt. dictSchauen Sie sich einfach den hübschen Druck an:

import json

def pp_json(json_thing, sort=True, indents=4):
    if type(json_thing) is str:
        print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents))
    else:
        print(json.dumps(json_thing, sort_keys=sort, indent=indents))
    return None

pp_json(your_json_string_or_dict)
Zelusp
quelle
14

Ich habe einmal eine prettyjson()Funktion geschrieben, um eine gut aussehende Ausgabe zu erzeugen. Sie können die Implementierung von diesem Repo abrufen .

Das Hauptmerkmal dieser Funktion ist, dass versucht wird, Diktat- und Listenelemente in einer Zeile zu halten, bis eine bestimmte maxlinelengtherreicht ist. Dies erzeugt weniger JSON-Zeilen, die Ausgabe sieht kompakter und leichter zu lesen aus.

Sie können diese Art von Ausgabe zum Beispiel erzeugen:

{
  "grid": {"port": "COM5"},
  "policy": {
    "movingaverage": 5,
    "hysteresis": 5,
    "fan1": {
      "name": "CPU",
      "signal": "cpu",
      "mode": "auto",
      "speed": 100,
      "curve": [[0, 75], [50, 75], [75, 100]]
    }
}

UPD 19. Dezember: Ich habe den Code in ein separates Repo gestellt , einige Fehler korrigiert und einige weitere Änderungen vorgenommen.

Andy
quelle
Ich halte diesen Formatierer für den besten der vorgeschlagenen und verdient mehr Gegenstimmen.
Thorhunter
13

Um über die Befehlszeile hübsch drucken und die Einrückung usw. steuern zu können, können Sie einen ähnlichen Alias ​​einrichten:

alias jsonpp="python -c 'import sys, json; print json.dumps(json.load(sys.stdin), sort_keys=True, indent=2)'"

Verwenden Sie den Alias ​​dann auf eine der folgenden Arten:

cat myfile.json | jsonpp
jsonpp < myfile.json
VP
quelle
11

Verwenden Sie pprint: https://docs.python.org/3.6/library/pprint.html

import pprint
pprint.pprint(json)

print() verglichen mit pprint.pprint()

print(json)
{'feed': {'title': 'W3Schools Home Page', 'title_detail': {'type': 'text/plain', 'language': None, 'base': '', 'value': 'W3Schools Home Page'}, 'links': [{'rel': 'alternate', 'type': 'text/html', 'href': 'https://www.w3schools.com'}], 'link': 'https://www.w3schools.com', 'subtitle': 'Free web building tutorials', 'subtitle_detail': {'type': 'text/html', 'language': None, 'base': '', 'value': 'Free web building tutorials'}}, 'entries': [], 'bozo': 0, 'encoding': 'utf-8', 'version': 'rss20', 'namespaces': {}}

pprint.pprint(json)
{'bozo': 0,
 'encoding': 'utf-8',
 'entries': [],
 'feed': {'link': 'https://www.w3schools.com',
          'links': [{'href': 'https://www.w3schools.com',
                     'rel': 'alternate',
                     'type': 'text/html'}],
          'subtitle': 'Free web building tutorials',
          'subtitle_detail': {'base': '',
                              'language': None,
                              'type': 'text/html',
                              'value': 'Free web building tutorials'},
          'title': 'W3Schools Home Page',
          'title_detail': {'base': '',
                           'language': None,
                           'type': 'text/plain',
                           'value': 'W3Schools Home Page'}},
 'namespaces': {},
 'version': 'rss20'}
Nakamoto
quelle
pprinterstellt kein gültiges JSON-Dokument.
Selurvedu
5

Hier ist ein einfaches Beispiel für das hübsche Drucken von JSON auf die Konsole in Python, ohne dass sich JSON als lokale Datei auf Ihrem Computer befinden muss:

import pprint
import json 
from urllib.request import urlopen # (Only used to get this example)

# Getting a JSON example for this example 
r = urlopen("https://mdn.github.io/fetch-examples/fetch-json/products.json")
text = r.read() 

# To print it
pprint.pprint(json.loads(text))
David Liu
quelle
Ich erhalte die folgende Fehlermeldung in Python 3: "TypeError: Das JSON-Objekt muss str sein, nicht 'Bytes'"
Mr. T
3
def saveJson(date,fileToSave):
    with open(fileToSave, 'w+') as fileToSave:
        json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)

Es funktioniert, um es anzuzeigen oder in einer Datei zu speichern.

Pablo Emmanuel De Leo
quelle
1

Ich denke, es ist besser, den JSON vorher zu analysieren, um Fehler zu vermeiden:

def format_response(response):
    try:
        parsed = json.loads(response.text)
    except JSONDecodeError:
        return response.text
    return json.dumps(parsed, ensure_ascii=True, indent=4)
p3quod
quelle
1

Sie könnten pprintjson versuchen .


Installation

$ pip3 install pprintjson

Verwendungszweck

Drucken Sie JSON aus einer Datei mithilfe der pprintjson-CLI.

$ pprintjson "./path/to/file.json"

Pretty Print JSON von einem Standard mit der pprintjson CLI.

$ echo '{ "a": 1, "b": "string", "c": true }' | pprintjson

Drucken Sie JSON mithilfe der pprintjson-CLI aus einem String.

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }'

Pretty print JSON aus einem String mit einem Einzug von 1.

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -i 1

Drucken Sie JSON hübsch aus einer Zeichenfolge und speichern Sie die Ausgabe in einer Datei output.json.

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -o ./output.json

Ausgabe

Geben Sie hier die Bildbeschreibung ein

Travis Clarke
quelle
0

Es ist alles andere als perfekt, aber es macht den Job.

data = data.replace(',"',',\n"')

Sie können es verbessern, Einrückungen hinzufügen und so weiter, aber wenn Sie nur einen saubereren JSON lesen möchten, ist dies der richtige Weg.

Francisco Perdomo
quelle