'Parse dpkg command output to JSON in Go

I'm trying to convert exec output to json format. I just want to read a single string from the output, what would be the right way to do it. I thought about jq also but didn't work for me.

Here is the code snippet:

package main

import (
        "fmt"
        "encoding/json"
        "os/exec"
)

type pkg struct {
        Package string `json:"package"`
        Version string `json:"version:"`
}

func main() {
        fmt.Println("Hello, 世界")
        cmd := exec.Command("dpkg", "-s", "tar")
        output, err := cmd.CombinedOutput()
        if err != nil {
                fmt.Printf("%v", err)
        }
        var xyz pkg
        if err := json.Unmarshal([]byte(output), &xyz); err != nil {
                fmt.Printf("\n%v %v\n", string(output), err)
        }
        fmt.Println(xyz)
}

Command output:

$ dpkg -s tar
Package: tar
Essential: yes
Status: install ok installed
Priority: required
Section: utils
Installed-Size: 3152
Maintainer: Janos Lenart <[email protected]>
Architecture: amd64
Multi-Arch: foreign
Version: 1.34+dfsg-1
Replaces: cpio (<< 2.4.2-39)
Pre-Depends: libacl1 (>= 2.2.23), libc6 (>= 2.28), libselinux1 (>= 3.1~)
Suggests: bzip2, ncompress, xz-utils, tar-scripts, tar-doc
Breaks: dpkg-dev (<< 1.14.26)
Conflicts: cpio (<= 2.4.2-38)
Description: GNU version of the tar archiving utility
 Tar is a program for packaging a set of files as a single archive in tar
 format.  The function it performs is conceptually similar to cpio, and to
 things like PKZIP in the DOS world.  It is heavily used by the Debian package
 management system, and is useful for performing system backups and exchanging
 sets of files with others.
Homepage: https://www.gnu.org/software/tar/

I'm getting the following error on json.Unmarshal:

invalid character 'P' looking for beginning of value



Solution 1:[1]

A simple solution could be use dpkg-query to format your desired output in json format:

package main

import (
        "fmt"
        "encoding/json"
        "os/exec"
)

type pkg struct {
        Package string `json:"package"`
        Version string `json:"version"`
}

func main() {
        cmd := exec.Command("dpkg-query", "-W", "-f={ \"package\": \"${Package}\", \"version\": \"${Version}\" }", "tar")

        output, err := cmd.CombinedOutput()
        if err != nil {
                fmt.Printf("%v", err)
        }
        fmt.Println(string(output))

        var xyz pkg
        if err := json.Unmarshal([]byte(output), &xyz); err != nil {
                fmt.Printf("\n%v %v\n", string(output), err)
        }

        fmt.Println(xyz.Package)
        fmt.Println(xyz.Version)
}

{ "package": "tar", "version": "1.34+dfsg-1" }
tar
1.34+dfsg-1

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 wiltonsr