狐的传说
我会将您的输入文件转换为 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,ID1,2,3,4,50,600,700,/dev/nvme0,/dev/nvme0n1,decoders:11a,2b,3c,4c,5d,6e,7f,/dev/nvme1,/dev/nvme1n1,decoders:22a,2b,2c,3,0,0,0,/dev/nvme0,/dev/nvme0n1,encoders:11,0,0,0,0,0,0,/dev/nvme1,/dev/nvme1n1,encoders:20,0,0,0,0,0,0,/dev/nvme0,/dev/nvme0n1,scalers:11,0,0,0,0,0,0,/dev/nvme1,/dev/nvme1n1,scalers:2NB在 Go 中为您的输入格式编写解析器应该不会那么困难
慕斯王
如何直接从您关心的 Go 文本开始?与使用 shell 实用程序相比,您在 Go 中拥有更多的控制权。这是一个小型状态机,用于查找前导文本“Num”以指示新项目的开始。下一行是标题,它被跳过,后面的行被转换为一个行,被添加到那个项目。在项目之间的边界和输入文本/文件的末尾,最后一个项目被添加到所有项目的集合中。package mainimport ( "bufio" "fmt" "regexp" "strings")var txt = `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 2Num item3: 1INDEX LOAD MODEL_LOAD INST MEM SHARE_MEM P2P_MEM DEVICE NAMESPACEi 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 []Rowfunc 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}我不知道有什么更好的方法来创建结构,但它是直接的,而且相当干净。