亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將 shell 輸出綁定到 Go 中的結構的最佳方法?

將 shell 輸出綁定到 Go 中的結構的最佳方法?

Go
達令說 2023-02-14 18:15:34
我有一些芯片在某些硬件上運行,我想將 shell 命令的輸出綁定到一個結構以進行報告/登錄。Num item1: 2INDEX LOAD MODEL_LOAD INST MEM  SHARE_MEM P2P_MEM DEVICE         NAMESPACE1     2    3          4    50    600         700       1     11a     2b    3c          4c    5d    6e         7f       2     2Num item2: 2INDEX LOAD MODEL_LOAD INST MEM  SHARE_MEM P2P_MEM DEVICE         NAMESPACE2a     2b    2c          3    0    0         0       1     11     0    0          0    0    0         0       2     2**************************************************試圖cat out.txt | grep -i "Num $1" -A 3 | grep -i nvme | tr -s ' ' | cut -d' ' -f1-7這實際上還不算太糟糕,我可以傳入一個 argdecoders或encoders并獲取每個芯片的負載指標。但是,我現在很好奇將它綁定到 Go 中的結構的最佳方法。目前,我能做的是編寫一個自定義解串器,例如: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 并綁定到結構或其他東西。
查看完整描述

2 回答

?
狐的傳說

TA貢獻1804條經驗 獲得超3個贊

我會將您的輸入文件轉換為 CSV,因為它適合原始表格數據,也因為 Go 語言在其標準庫中有一個 CSV 編碼器/解碼器:


awk -v OFS=',' '

    $1 == "Num" {

        count = $3

        type = $2


        getline

        if ( !header++ ) {

            $(NF+1) = "ID"

            print

        }

        for ( id = 1; id <= count; id++ ) {

            getline

            $(NF+1) = type id

            print

        }

    }

' file.txt

警告:代碼不會對字段進行 CSV 轉義


INDEX,LOAD,MODEL_LOAD,INST,MEM,SHARE_MEM,P2P_MEM,DEVICE,NAMESPACE,ID

1,2,3,4,50,600,700,/dev/nvme0,/dev/nvme0n1,decoders:1

1a,2b,3c,4c,5d,6e,7f,/dev/nvme1,/dev/nvme1n1,decoders:2

2a,2b,2c,3,0,0,0,/dev/nvme0,/dev/nvme0n1,encoders:1

1,0,0,0,0,0,0,/dev/nvme1,/dev/nvme1n1,encoders:2

0,0,0,0,0,0,0,/dev/nvme0,/dev/nvme0n1,scalers:1

1,0,0,0,0,0,0,/dev/nvme1,/dev/nvme1n1,scalers:2

NB在 Go 中為您的輸入格式編寫解析器應該不會那么困難


查看完整回答
反對 回復 2023-02-14
?
慕斯王

TA貢獻1864條經驗 獲得超2個贊

如何直接從您關心的 Go 文本開始?與使用 shell 實用程序相比,您在 Go 中擁有更多的控制權。


這是一個小型狀態機,用于查找前導文本“Num”以指示新項目的開始。下一行是標題,它被跳過,后面的行被轉換為一個行,被添加到那個項目。在項目之間的邊界和輸入文本/文件的末尾,最后一個項目被添加到所有項目的集合中。


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)

        }

    }

}

打印以下內容:


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}

我不知道有什么更好的方法來創建結構,但它是直接的,而且相當干凈。


查看完整回答
反對 回復 2023-02-14
  • 2 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號