Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use golang to convert a multi-line json to one-line json?

Tags:

json

go

How can I convert a multi-line json to a one-line json using Go?

From:

{
          "release_date": "2004-11-09",
          "status": "retired",
          "engine": "Gecko",
          "engine_version": "1.7"
        }

To:

{"release_date":"2004-11-09","status":"retired","engine":"Gecko","engine_version":"1.7"}

like image 599
flexwang Avatar asked Oct 12 '25 03:10

flexwang


2 Answers

json.Compact() does exactly this:

func Compact(dst *bytes.Buffer, src []byte) error

Compact appends to dst the JSON-encoded src with insignificant space characters elided.

json.Compact() is superior to unmarshaling and marshaling again, as it works with any valid JSON, and is much-much faster (it doesn't create and throw away Go values). It's also superior to using any regexp, again, it's much-much faster and regexp does not understand JSON syntax fully, so it might result in data loss.

For example:

func main() {
    dst := &bytes.Buffer{}
    if err := json.Compact(dst, []byte(src)); err != nil {
        panic(err)
    }
    fmt.Println(dst.String())
}

const src = `{
          "release_date": "2004-11-09",
          "status": "retired",
          "engine": "Gecko",
          "engine_version": "1.7"
        }`

This will output (try it on the Go Playground):

{"release_date":"2004-11-09","status":"retired","engine":"Gecko","engine_version":"1.7"}
like image 149
icza Avatar answered Oct 15 '25 15:10

icza


Unmarshal the multi-line JSON into a struct (or alternatively a map[string]any{}) and then marshal it to a string without any indent options. So, something like this:

    v := struct {
        ReleaseDate string `json:"release_date"`
        Status      string `json:"status"`
        Engine      string `json:"engine"`
        Version     string `json:"engine_version"`
    }{}

    if err := json.Unmarshal([]byte(s), &v); err != nil {
        fmt.Printf("ERROR: %v\n", err)
    } else if bytes, err := json.Marshal(v); err != nil {
        fmt.Printf("ERROR: %v\n", err)
    } else {
        fmt.Printf("%v\n", string(bytes))
    }

(Go Playground)

like image 42
tonys Avatar answered Oct 15 '25 15:10

tonys