programing tip

Go를 사용하여 JSON을 예쁘게 인쇄하려면 어떻게해야합니까?

itbloger 2020. 6. 6. 08:48
반응형

Go를 사용하여 JSON을 예쁘게 인쇄하려면 어떻게해야합니까?


누구나 Go에서 JSON 출력을 예쁘게 인쇄하는 간단한 방법을 알고 있습니까?

주식 http://golang.org/pkg/encoding/json/ 패키지에는 이것에 대한 기능이 포함되어 있지 않은 것 같으며 (편집 : 허용, 답변 있음) 빠른 Google은 명백한 것을 나타내지 않습니다.

내가 찾고있는 용도는 결과를 예쁘게 인쇄하고 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)
}

편집 되돌아 보면, 이것은 관용적이지 않은 바둑입니다. 이와 같은 작은 도우미 기능은 복잡한 단계를 추가합니다. 일반적으로 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


Go에서 색상이 지정된 문자열에 JSON을 마샬링하는 빠르고 고품질의 방법이 없기 때문에 좌절했기 때문에 ColorJSON 이라는 내 마샬 러를 작성했습니다 .

그것으로 아주 작은 코드를 사용하여 다음과 같은 출력을 쉽게 생성 할 수 있습니다.

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

지금 문서를 작성하고 있지만 솔루션을 공유하게되어 기뻤습니다.


여기 내가 사용하는 것이 있습니다. JSON을 예쁘게 인쇄하지 못하면 원래 문자열을 반환합니다. 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()
}

내 해결책은 다음과 같습니다 .

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 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)

}

참고 URL : https://stackoverflow.com/questions/19038598/how-can-i-pretty-print-json-using-go

반응형