JSON-Formatierungs-Skript

Aus Laub-Home Wiki

Über den JSON-Standard können Daten in menschenlesbarer Sprache ausgetauscht werden (ähnlich wie bei XML). Die meisten APIs geben ihre Ausgaben jedoch als eine einzige, sehr lange Zeile wieder, was sehr unübersichtlich ist und daher das Debugging erheblich erschweren kann. Das unten angegebene Skript formatiert eine solche Ausgabe mit Zeilenumbrüchen und rückt diese korrekt in die Ebenen ein.

Abhängigkeiten

Das Skript benötigt folgende Programme:

  • awk
  • sed
  • cat

Das Skript geht davon aus, dass die Objekt-Keys alle von doppelten Anführungszeichen umschlossen sind, wie es RFC-4627 fordert. Auch geht es davon aus, dass es aufgrund der Anforderung keinen Whitespace (beliebig viele Leerzeichen und Zeilenumbrüche zwischen Elementen) gibt.

Skript

#!/bin/bash
#########################################################################
#Name: format-json.sh
#Subscription:
#This Skritp formats JSON output from APIs which return one long line
#by Simon A. Skolik
#
#License:
#This program is free software: you can redistribute it and/or modify it
#under the terms of the GNU General Public License as published by the
#Free Software Foundation, either version 3 of the License, or (at your option)
#any later version.
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
#or FITNESS FOR A PARTICULAR PURPOSE.
#########################################################################
#Set the language
export LANG="en_US.UTF-8"
#Load the Pathes
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

jsoncode="$(cat /dev/stdin)"

if [ "$1" == "" ]; then
	myindent=3
else
	myindent=$1
fi

echo "$jsoncode" | sed -E -e '
# Umbruch des ersten Objekt-Markters
s/(^\{)/\1\
/g

# Grobe Trennung der einzelnen Paare
s/("([^"]|\\")+":("([^"]|\\")*",|[^][{,}]+,))/\1\
/g

# Umbruch von geoeffneten Array/Objekt Elementen
s/("([^"]|\\")*":)([[{]+)/\1\
\3\
/g

# Umbrechen von schliessenden Arrays auf eine eigene Zeile
s/(],)("([^"]|\\")+":)/\
\1\
\2/g

# Umbrechen von geschlossenen Objekt/Array-Markern am Ende von Keys
s/("([^"]|\\")+":("([^"]|\\")*"|[^][{,}]+))([]}]+)/\1\
\5/g

# Umbruch von mehreren geschlossenen Objekt-Markern
: arraymarker
s/(\n}+)(})/\1\
\2/g
t arraymarker

# Umbruch von geschlossenen Objekten in Arrays
s/(\n},)(.)/\1\
\2/g

# Umbrechen von geoeffneten Objekten innerhalb von Arrays
s/("([^"]|\\")+",|[^][}{,]+,)(\{)("([^"]|\\")+":)/\1\
\3\
\4/g

# Umbrechen von Arrays innerhalb von Arrays
s/("([^"]|\\")+",|[^][}{,]+,)(\[)("([^"]|\\")+",|[^][}{,]+,)/\1\
\3\
\4/g

# Umbrechen von Schliessenden Arrays innerhalb von Arrays
s/("([^"]|\\")+"|[^][}{,]+)(],?)("([^"]|\\")+",|[^][}{,]+,)/\1\
\3\
\4/g

# Umbrechen von Array-Elementen
: arrayumbruch
s/(\n("([^"]|\\")+"|[^][}{,]+),)("([^"]|\\")+"|[^][}{,[:space:]]+)/\1\
\4/g
t arrayumbruch

# Umbrechen von Array/Object-Markern, arbeitet mit Spruengen
: markerumbruch
s/(\n[][}{]+)([][}{](\n|$))/\1\
\2/g
t markerumbruch

# Entfernen von Leerzeilen
s/\n+\n/\
/g
' | awk 'BEGIN { currentindent = 0; indent = '$myindent'; }
/^]|^}/{ currentindent -= indent; }
{
	for (i = 0; i < currentindent; i++)
		printf " ";
	print $0;
}
/^\{|^\[/ { currentindent += indent; }'

Dieses Skript wurde erfolgreich unter Rasbian Linux 7.0 und MacOS X 10.8.3 getestet.

Usage

Das Skript bezieht seine Eingaben von STDIN. Auch kann als Parameter übergeben werden, wie viele Leerzeichen als Einschub benutzt werden sollen (Standard ist 3).

cat json-example.txt | ./format-json.sh [number of spaces]

Installation

Das Skript einfach als Text-Datei auf einem Unix-System speichern und die Ausführungsrechte setzten:

vi format-json.sh
chmod +x format-json.sh

Siehe auch