Golang шаблон для форматирования docker ps выводится как JSON - PullRequest
4 голосов
/ 04 мая 2020

Мне интересно, возможно ли добавить дополнительное форматирование, необходимое для того, чтобы этот вывод был действительной строкой JSON. Для этого мне нужен один символ в начале, по одному в каждой строке, кроме последней, а затем один последний символ.

У меня сейчас есть это;

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

Я не могу понять, как использовать Go, чтобы просто выделить один символ в начале (или даже если это возможно).

Ответы [ 2 ]

3 голосов
/ 04 мая 2020

Проблема в том, что вы указываете шаблон, но этот шаблон применяется индивидуально для каждого из ваших контейнеров, и каждый результат шаблона отображается в новой строке. Ваш шаблон применяется не к списку элементов, а к отдельным элементам, и то, как выводится результат (как соединяются строки), не находится под вашим контролем.

Но вы можете достичь того, чего хотите, с помощью 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.

Таким образом, ваш «желаемый» вывод представляет собой последовательность добавлений: ] к выходу docker и к выходу одиночного [.

Таким образом, решение в вашем случае:

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

Это будет выводить:

[
{ "85c4c597bef9" : "addon_a0d7b954_nodered"},{ "ec3c55af0497" : "addon_a0d7b954_appdaemon"},{ "63e3081fbe42" : "addon_a0d7b954_logviewer"}
]
0 голосов
/ 04 мая 2020

a go -i sh решение может выглядеть следующим образом, хотя я не уверен, как оно будет вести себя с вложенными объектами.

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

...