GoでJSON出力をきれいに出力する簡単な方法を知っている人はいますか?
株式http://golang.org/pkg/encoding/json/パッケージには、このための機能が含ましていないようです(編集:それは、受け入れ答えを見ずに)し、簡単にGoogleは明らかに何かを上げていません。
私が探している用途は、結果をきれいに出力することとjson.Marshal
、どこからでもJSONでいっぱいの文字列をフォーマットすることの両方なので、デバッグ目的で読みやすくなっています。
GoでJSON出力をきれいに出力する簡単な方法を知っている人はいますか?
株式http://golang.org/pkg/encoding/json/パッケージには、このための機能が含ましていないようです(編集:それは、受け入れ答えを見ずに)し、簡単にGoogleは明らかに何かを上げていません。
私が探している用途は、結果をきれいに出力することとjson.Marshal
、どこからでもJSONでいっぱいの文字列をフォーマットすることの両方なので、デバッグ目的で読みやすくなっています。
回答:
プリティプリントとは、インデントされているという意味だと思います。
{
"data": 1234
}
のではなく
{"data":1234}
これを行う最も簡単な方法はをMarshalIndent
使用することですindent
。これにより、引数を使用してインデントする方法を指定できます。したがって、json.MarshalIndent(data, "", " ")
インデントに4つのスペースを使用してpretty-printします。
json.MarshalIndent(data, "", "\t")
タブが必要な場合。
json.MarshalIndent(data, "", "🐱")
猫が欲しいなら 申し訳ありません
json.MarshalIndent(data, "", "\t🐱")
あなたが欲しいなら...トラ猫... ごめんなさい
JSONに変換したいオブジェクトがある場合、受け入れられた答えは素晴らしいです。この質問では、JSON文字列だけをきれいに出力することについても触れられています。POST要求(特にCSP違反レポート)からJSONをかなりログに記録したかっただけです。
を使用MarshalIndent
するには、Unmarshal
それをオブジェクトに組み込む必要があります。あなたがそれを必要とするなら、それのために行きますが、私はしませんでした。バイト配列をプリティプリントするだけの場合Indent
は、plain がお勧めです。
これが私が終わったものです:
import (
"bytes"
"encoding/json"
"log"
"net/http"
)
func HandleCSPViolationRequest(w http.ResponseWriter, req *http.Request) {
body := App.MustReadBody(req, w)
if body == nil {
return
}
var prettyJSON bytes.Buffer
error := json.Indent(&prettyJSON, body, "", "\t")
if error != nil {
log.Println("JSON parse error: ", error)
App.BadRequest(w)
return
}
log.Println("CSP Violation:", string(prettyJSON.Bytes()))
}
より良いメモリ使用のために、私はこれがより良いと思います:
var out io.Writer
enc := json.NewEncoder(out)
enc.SetIndent("", " ")
if err := enc.Encode(data); err != nil {
panic(err)
}
SetIndent
最近追加されますか?それは本質的にほとんど知られていない。
SetIndent
(元々の名前Indent
は明らか2016年3月追加され、この質問はもともと頼まれた後3年程度だったゴー1.7でリリースされました): github.com/golang/go/commit/...の github.com/golang/go/commit/ …
Goで色付けされた文字列にJSONをマーシャリングする高速で高品質な方法がないことに不満を感じていたので、ColorJSONという独自のマーシャラーを作成しました。
これにより、非常に少ないコードを使用して、次のような出力を簡単に生成できます。
package main
import (
"fmt"
"encoding/json"
"github.com/TylerBrock/colorjson"
)
func main() {
str := `{
"str": "foo",
"num": 100,
"bool": false,
"null": null,
"array": ["foo", "bar", "baz"],
"obj": { "a": 1, "b": 2 }
}`
var obj map[string]interface{}
json.Unmarshal([]byte(str), &obj)
// Make a custom formatter with indent set
f := colorjson.NewFormatter()
f.Indent = 4
// Marshall the Colorized JSON
s, _ := f.Marshal(obj)
fmt.Println(string(s))
}
現在、そのドキュメントを書いていますが、自分のソリューションを共有できることに興奮しました。
編集振り返ってみると、これは慣用ではないGoです。このような小さなヘルパー関数は、さらに複雑なステップを追加します。一般に、囲碁の哲学では、1つのトリッキーなラインよりも3つのシンプルなラインを含めることを好みます。
@robyoderが述べたように、それjson.Indent
が方法です。私はこの小さなprettyprint
関数を追加すると思いました:
package main
import (
"bytes"
"encoding/json"
"fmt"
)
//dont do this, see above edit
func prettyprint(b []byte) ([]byte, error) {
var out bytes.Buffer
err := json.Indent(&out, b, "", " ")
return out.Bytes(), err
}
func main() {
b := []byte(`{"hello": "123"}`)
b, _ = prettyprint(b)
fmt.Printf("%s", b)
}
https://go-sandbox.com/#/R4LWpkkHINまたはhttp://play.golang.org/p/R4LWpkkHIN
これが私の解決策です:
import (
"bytes"
"encoding/json"
)
const (
empty = ""
tab = "\t"
)
func PrettyJson(data interface{}) (string, error) {
buffer := new(bytes.Buffer)
encoder := json.NewEncoder(buffer)
encoder.SetIndent(empty, tab)
err := encoder.Encode(data)
if err != nil {
return empty, err
}
return buffer.String(), nil
}
Goのシンプルな既成のきれいなプリンター。次の方法でバイナリにコンパイルできます。
go build -o jsonformat jsonformat.go
標準入力から読み取り、標準出力に書き込み、インデントを設定できます。
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
)
func main() {
indent := flag.String("indent", " ", "indentation string/character for formatter")
flag.Parse()
src, err := ioutil.ReadAll(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "problem reading: %s", err)
os.Exit(1)
}
dst := &bytes.Buffer{}
if err := json.Indent(dst, src, "", *indent); err != nil {
fmt.Fprintf(os.Stderr, "problem formatting: %s", err)
os.Exit(1)
}
if _, err = dst.WriteTo(os.Stdout); err != nil {
fmt.Fprintf(os.Stderr, "problem writing: %s", err)
os.Exit(1)
}
}
次のようなbashコマンドを実行できます。
cat myfile | jsonformat | grep "key"
package cube
import (
"encoding/json"
"fmt"
"github.com/magiconair/properties/assert"
"k8s.io/api/rbac/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
)
func TestRole(t *testing.T) {
clusterRoleBind := &v1beta1.ClusterRoleBinding{
ObjectMeta: v1.ObjectMeta{
Name: "serviceaccounts-cluster-admin",
},
RoleRef: v1beta1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "cluster-admin",
},
Subjects: []v1beta1.Subject{{
Kind: "Group",
APIGroup: "rbac.authorization.k8s.io",
Name: "system:serviceaccounts",
},
},
}
b, err := json.MarshalIndent(clusterRoleBind, "", " ")
assert.Equal(t, nil, err)
fmt.Println(string(b))
}
私は行くのはちょっと新しいですが、これは私がこれまでに集めたものです:
package srf
import (
"bytes"
"encoding/json"
"os"
)
func WriteDataToFileAsJSON(data interface{}, filedir string) (int, error) {
//write data as buffer to json encoder
buffer := new(bytes.Buffer)
encoder := json.NewEncoder(buffer)
encoder.SetIndent("", "\t")
err := encoder.Encode(data)
if err != nil {
return 0, err
}
file, err := os.OpenFile(filedir, os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
return 0, err
}
n, err := file.Write(buffer.Bytes())
if err != nil {
return 0, err
}
return n, nil
}
これは関数の実行であり、単なる標準です
b, _ := json.MarshalIndent(SomeType, "", "\t")
コード:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
minerals "./minerals"
srf "./srf"
)
func main() {
//array of Test struct
var SomeType [10]minerals.Test
//Create 10 units of some random data to write
for a := 0; a < 10; a++ {
SomeType[a] = minerals.Test{
Name: "Rand",
Id: 123,
A: "desc",
Num: 999,
Link: "somelink",
People: []string{"John Doe", "Aby Daby"},
}
}
//writes aditional data to existing file, or creates a new file
n, err := srf.WriteDataToFileAsJSON(SomeType, "test2.json")
if err != nil {
log.Fatal(err)
}
fmt.Println("srf printed ", n, " bytes to ", "test2.json")
//overrides previous file
b, _ := json.MarshalIndent(SomeType, "", "\t")
ioutil.WriteFile("test.json", b, 0644)
}
//You can do it with json.MarshalIndent(data, "", " ")
package main
import(
"fmt"
"encoding/json" //Import package
)
//Create struct
type Users struct {
ID int
NAME string
}
//Asign struct
var user []Users
func main() {
//Append data to variable user
user = append(user, Users{1, "Saturn Rings"})
//Use json package the blank spaces are for the indent
data, _ := json.MarshalIndent(user, "", " ")
//Print json formatted
fmt.Println(string(data))
}
{name: "value"}
大丈夫ではありません。Go JSONライブラリ関数でのみ機能します。{"name": "value"}