Golang 模板格式化 docker ps 输出为 JSON

Golang template to format docker ps output as JSON

我想知道是否可以添加使此输出成为有效 JSON 字符串所需的额外格式。为此,我需要在开头有一个字符,除最后一行外每行都有一个字符,然后是最后一个字符。

我目前有这个;

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

我不知道如何使用 Go 只在开头输出一个字符(或者即使可能)。

问题在于您指定了一个模板,但该模板会单独应用于您的每个容器,并且每个模板结果都在一个新行中呈现。你的模板不是应用于项目列表,而是应用于单个项目,结果如何输出(线条如何连接)不在你的控制范围内。

但是您可以使用 linux 命令实现您想要的。

此代码演示了您的模板是如何执行的:

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

这会输出您当前拥有的内容(在 Go Playground 上尝试):

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

您可以使用 paste 像这样用逗号连接行:

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

最后一件事:添加一个 [ 并添加一个 ] 使其成为一个有效的 JSON 数组。

要将某些内容附加到命令的输出,您可以使用

echo something | (command && cat)

要省略由 echo 引起的换行,您可以使用 echo -n.

因此您的 "wished" 输出是一系列附加:]docker 的输出,以及单个 [.[= 的输出25=]

所以你的解决方案是:

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

这将输出:

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

go-ish 解决方案可能看起来像这样,尽管我不确定它如何处理嵌套对象。

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "log"
    "os"
)

func main() {
    dec := json.NewDecoder(os.Stdin)
    enc := json.NewEncoder(os.Stdout)
    fmt.Println("[")
    d := map[string]interface{}{}
    var i int
    for {
        err := dec.Decode(&d)
        if err != nil {
            if err == io.EOF {
                break
            }
            log.Println(err)
            continue
        }
        if i > 0 {
            fmt.Println(",")
        }
        enc.Encode(d)
        i++
    }
    fmt.Println("]")
}

然后,docker ps -a --format "{{json .}}" | jq "{ID, Names}" | go run gow/src/test/jsonl/main.go