首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go中将shell输出绑定到结构的最佳方法?

Go中将shell输出绑定到结构的最佳方法?
EN

Stack Overflow用户
提问于 2022-09-20 16:40:13
回答 1查看 96关注 0票数 3

我在一些硬件上运行了一些芯片,我希望将shell命令的输出绑定到struct上,以便进行报告/登录。

代码语言:javascript
复制
Num item1: 2
INDEX LOAD MODEL_LOAD INST MEM  SHARE_MEM P2P_MEM DEVICE         NAMESPACE
1     2    3          4    50    600         700       1     1
1a     2b    3c          4c    5d    6e         7f       2     2
Num item2: 2
INDEX LOAD MODEL_LOAD INST MEM  SHARE_MEM P2P_MEM DEVICE         NAMESPACE
2a     2b    2c          3    0    0         0       1     1
1     0    0          0    0    0         0       2     2
**************************************************

尝试

代码语言:javascript
复制
cat out.txt | grep -i "Num $1" -A 3 | grep -i nvme | tr -s ' ' | cut -d' ' -f1-7

这其实还不算太糟,我可以传入一个像decodersencoders这样的arg,并为每个芯片获取负载度量。但是,我现在很好奇,最好的方法是将它绑定到结构中。

目前,我可以做的是从以下内容编写自定义反序列化器的代码:

代码语言:javascript
复制
func main() {
    out, err := exec.Command("/bin/sh", "metrics.sh", "encoders").Output()
    if err != nil {
        fmt.Println(err)
        log.Fatal(err)
    }

    fmt.Println(string(out))
}

但我觉得必须有更好的方法,比如输出为JSON,并绑定到结构或其他东西。

EN

回答 1

Stack Overflow用户

发布于 2022-09-21 08:13:00

直接从你关心的文字开始怎么样?在Go中,您将拥有比使用shell实用程序更多的控制权。

这是一个小状态机,它查找前面的文本"Num",以指示新项的开始。下一行是标题,它被跳过,下面的行被转换为行,行被添加到该项中。在项之间的边界和输入文本/文件的末尾,最后一个项被添加到所有项的集合中。

代码语言:javascript
复制
package main

import (
    "bufio"
    "fmt"
    "regexp"
    "strings"
)

var txt = `
Num item1: 2
INDEX LOAD MODEL_LOAD INST MEM  SHARE_MEM P2P_MEM DEVICE         NAMESPACE
1     2    3          4    50    600         700       1     1
1a     2b    3c          4c    5d    6e         7f       2     2
Num item2: 2
INDEX LOAD MODEL_LOAD INST MEM  SHARE_MEM P2P_MEM DEVICE         NAMESPACE
2a     2b    2c          3    0    0         0       1     1
1     0    0          0    0    0         0       2     2
Num item3: 1
INDEX LOAD MODEL_LOAD INST MEM  SHARE_MEM P2P_MEM DEVICE         NAMESPACE
i     iib    iic          iii    zero    zero         zero       i     i
**************************************************
`

var columns = regexp.MustCompile(`\s+`)

type Row struct {
    Index,
    Load,
    Model_Load,
    Inst_Mem,
    Share_Mem,
    P2p_Mem,
    Device,
    Namespace string
}

type Item []Row

func main() {
    r := strings.NewReader(txt)
    scanner := bufio.NewScanner(r)

    items := make([]Item, 0)

    var item Item
    for scanner.Scan() {
        line := scanner.Text()
        line = strings.TrimSpace(line)

        if len(line) == 0 ||
            strings.HasPrefix(line, "***") {
            continue
        }

        // find beginning of an "item": if any previous item, save it and
        // reset item to append future rows; skip header line; continue
        if strings.HasPrefix(line, "Num item") {
            if len(item) > 0 {
                items = append(items, item)
                item = make(Item, 0)
            }
            scanner.Scan() // skip header
            continue
        }

        cols := columns.Split(line, -1)
        row := Row{cols[0], cols[1], cols[2], cols[3], cols[4], cols[5], cols[6], cols[7]}
        item = append(item, row)
    }

    // deal with last/trailing item
    if len(item) > 0 {
        items = append(items, item)
    }

    for i, item := range items {
        fmt.Printf("Item %d\n", i+1)
        for _, row := range item {
            fmt.Println(row)
        }
    }
}

打印如下:

代码语言:javascript
复制
Item 1
{1 2 3 4 50 600 700 1}
{1a 2b 3c 4c 5d 6e 7f 2}
Item 2
{2a 2b 2c 3 0 0 0 1}
{1 0 0 0 0 0 0 2}
Item 3
{i iib iic iii zero zero zero i}

我不知道有什么更好的方法来创建这个结构,但是它是直接的,而且相当干净。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73790001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档