GoでJSON出力をきれいに印刷する簡単な方法を知っている人はいますか?
在庫 http://golang.org/pkg/encoding/json/ パッケージにはこの機能が含まれていないようです (編集:あります、受け入れられた答えを参照してください)そして、速いグーグルは明白な何かを見せません。
私が探している用途は、json.Marshal
の結果をきれいに表示することと、どこからでもJSONで満たされた文字列をフォーマットするだけであるため、デバッグ目的で読みやすくなります。
プリティプリントとは、インデントされていることを意味すると思います
{
"data": 1234
}
のではなく
{"data":1234}
これを行う最も簡単な方法は MarshalIndent
を使用することです。これにより、indent
引数を使用してインデントする方法を指定できます。したがって、json.MarshalIndent(data, "", " ")
はインデントに4つのスペースを使用してきれいに印刷します。
JSONに変換したいオブジェクトがある場合、受け入れられる答えは素晴らしいです。質問では、JSON文字列だけをきれいに印刷することにも言及していますが、それが私がやろうとしていたことです。 POSTリクエスト(具体的には CSP違反レポート )からJSONをきれいに記録したかっただけです。
MarshalIndent
を使用するには、オブジェクトにUnmarshal
する必要があります。あなたがそれを必要とするならば、それのために行きなさい、しかし私はしませんでした。バイト配列をきれいに表示する必要がある場合は、プレーン Indent
が友達です。
ここに私が終わったものがあります:
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)
}
Edit振り返ってみると、これは非慣用的なGoです。このような小さなヘルパー関数は、さらに複雑なステップを追加します。一般に、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
JSONをGoで色付けされた文字列にマーシャリングするための高速で高品質の方法がないことに不満を感じていたので、 ColorJSON と呼ばれる自分のマーシャラーを作成しました。
これにより、ごくわずかなコードを使用して、このような出力を簡単に生成できます。
package main
import (
"fmt"
"github.com/TylerBrock/colorjson"
"encoding/json"
)
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))
}
私は今、そのためのドキュメントを書いていますが、私のソリューションを共有することに興奮しました。
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
}
これが私が使用するものです。 JSONをきれいに印刷できない場合は、元の文字列を返すだけです。 should JSONを含むHTTP応答の印刷に役立ちます。
import (
"encoding/json"
"bytes"
)
func jsonPrettyPrint(in string) string {
var out bytes.Buffer
err := json.Indent(&out, []byte(in), "", "\t")
if err != nil {
return in
}
return out.String()
}
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 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)
}