Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang template to format docker ps output as JSON

I am wondering if it is possible to add the additional formating required to make this output a valid JSON string. To do so I need one character at the start, one on every line except the last, and then one final character.

I currently have this;

$ sudo docker ps --format "{ \"{{.ID}}\" : \"{{.Names}}\"}"
{ "85c4c597bef9" : "addon_a0d7b954_nodered"}
{ "ec3c55af0497" : "addon_a0d7b954_appdaemon"}
{ "63e3081fbe42" : "addon_a0d7b954_logviewer"}

I cannot work out how to use Go to just put out a single character at the start (or even if it is possible).

like image 533
Brian Avatar asked Oct 22 '25 15:10

Brian


1 Answers

The problem is that you specify a template, but that template is applied individually on each of your containers, and each template result is rendered in a new line. Your template does not apply to a list of items, but to individual items, and how the result is outputted (how the lines are joined) is not in your control.

But you may achieve what you want with linux commands.

This code demonstrates how your template is executed:

src := "{ \"{{.ID}}\" : \"{{.Names}}\"}"
t := template.Must(template.New("").Parse(src))

ps := []map[string]string{
    {"ID": "85c4c597bef9", "Names": "addon_a0d7b954_nodered"},
    {"ID": "ec3c55af0497", "Names": "addon_a0d7b954_appdaemon"},
    {"ID": "63e3081fbe42", "Names": "addon_a0d7b954_logviewer"},
}

for _, p := range ps {
    if err := t.Execute(os.Stdout, p); err != nil {
        panic(err)
    }
    fmt.Println()
}

This outputs what you have currently (try it on the Go Playground):

{ "85c4c597bef9" : "addon_a0d7b954_nodered"}
{ "ec3c55af0497" : "addon_a0d7b954_appdaemon"}
{ "63e3081fbe42" : "addon_a0d7b954_logviewer"}

You may use paste to join the lines with a comma like this:

docker ps --format "{ \"{{.ID}}\" : \"{{.Names}}\"}" |paste -sd','

One last thing: prepend a [ and append a ] so it becomes a valid JSON array.

To append something to a command's output, you may use

echo something | (command && cat)

To omit the newline caused by echo, you may use echo -n.

So your "wished" output is a series of appends: ] to the output of docker, and that to the output of the single [.

So the solution in your case:

echo ] | (docker ps --format "{ \"{{.ID}}\" : \"{{.Names}}\"}" | paste -sd',' && cat) | (echo [ && cat)

This will output:

[
{ "85c4c597bef9" : "addon_a0d7b954_nodered"},{ "ec3c55af0497" : "addon_a0d7b954_appdaemon"},{ "63e3081fbe42" : "addon_a0d7b954_logviewer"}
]
like image 152
icza Avatar answered Oct 25 '25 09:10

icza