programing

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

javamemo 2023. 3. 21. 21:25
반응형

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

이동 중에 JSON 출력을 예쁘게 인쇄할 수 있는 간단한 방법을 아는 사람이 있습니까?

결과를 예쁘게 인쇄하고 싶다json.Marshal읽기 쉽게 기존 JSON 문자열을 포맷합니다.

MarshalIndent 를 사용하면 들여쓰기 및 띄어쓰기로 JSON을 출력할 수 있습니다.예를 들어 다음과 같습니다.

{
    "data": 1234
}

indent인수에는 들여쓸 일련의 문자를 지정합니다.따라서,json.MarshalIndent(data, "", " ")네 칸을 들여쓰면 예쁘게 인쇄됩니다.

JSON으로 만들고 싶은 오브젝트가 있다면 좋은 답변입니다.이 질문에는 JSON 문자열만 예쁘게 인쇄하는 것도 언급되어 있습니다.그게 바로 제가 하려고 했던 것입니다.POST 요청(특히 CSP 위반 보고서)에서 JSON을 예쁘게 기록하려고 합니다.

사용방법MarshalIndent, 다음과 같이 해야 합니다.Unmarshal물건으로 만들 수 있습니다.그게 필요하면 해봐, 하지만 난 그러지 않았어.바이트 배열만 예쁘게 인쇄해야 한다면 플레인(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)
}

바둑에서 색칠된 문자열에 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))
}

저는 지금 그 문서를 작성하고 있지만, 저의 솔루션을 공유하게 되어 매우 기뻤습니다.

편집 돌이켜보면, 이것은 비이성 Go입니다.이와 같은 작은 도우미 기능은 복잡함을 더합니다.일반적으로 바둑 철학은 까다로운 한 줄보다 간단한 세 줄을 포함하는 것을 선호합니다.


@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/ #/R4LWpkhIN 또는 http://play.golang.org/p/R4LWpkkHIN

이게 내가 쓰는 거야.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()
}
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))
}

어떻게 생겼는지

저의 솔루션은 다음과 같습니다.

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

http를 사용한 다른 예.ResponseWriter.

import (
    "encoding/json"
    "net/http"
)

func main() {
    var w http.ResponseWriter

    type About struct {
        ProgName string
        Version string
    }
    goObj := About{ProgName: "demo", Version: "0.0.0"}
    beautifulJsonByte, err := json.MarshalIndent(goObj, "", "  ")
    if err != nil {
        panic(err)
    }
    _, _ = w.Write(beautifulJsonByte)
}

산출량

{
  "ProgName": "demo",
  "Version": "0.0.0"
}

놀이터로 이동

JSON을 예쁘게 인쇄하기 위한 명령줄 유틸리티를 만드는 경우


package main

import ("fmt"
  "encoding/json"
  "os"
  "bufio"
  "bytes"
)


func main(){

    var out bytes.Buffer

    reader := bufio.NewReader(os.Stdin)
    text, _ := reader.ReadString('\n')

    err := json.Indent(&out, []byte(text), "", "  ")
    if err != nil {
      fmt.Println(err)
    }

    fmt.Println(string(out.Bytes()))
}

echo "{\"boo\":\"moo\"}" | go run main.go 

그럼 다음 출력이 생성됩니다.

{
  "boo": "moo"
}

자유롭게 2진수를 구축하다

go build main.go

투하하다/usr/local/bin

심플한 기성품 프린터로 이동 중에도 예쁜 프린터.다음을 통해 바이너리로 컴파일할 수 있습니다.

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)

}

json.MarshalIndentstring

★★★★★★★★★★★★★★★★★.easyPrint는 인수를 .data(모든 유형의 데이터)를 사용하여 원하는(예쁜) JSON 형식으로 인쇄합니다.

import (
  "encoding/json"
  "log"
)

func easyPrint(data interface{}) {
  manifestJson, _ := json.MarshalIndent(data, "", "  ")

  log.Println(string(manifestJson))
}

★★★★★★★★★★★★★★★★ name★★★★★★ 。

TODO: 인수하다name★★★★★★★★★★★★★★★★★★.

func easyPrint(data interface{}, name string) {
  manifestJson, _ := json.MarshalIndent(data, "", "  ")

  log.Println(name + " ->", string(manifestJson))
}

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

반응형