2 回答
TA贡献1804条经验 获得超3个赞
我会将您的输入文件转换为 CSV,因为它适合原始表格数据,也因为 Go 语言在其标准库中有一个 CSV 编码器/解码器:
awk -v OFS=',' '
$1 == "Num" {
count = $3
type = $2
getline
if ( !header++ ) {
$(NF+1) = "ID"
}
for ( id = 1; id <= count; id++ ) {
getline
$(NF+1) = type id
}
}
' 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 中为您的输入格式编写解析器应该不会那么困难
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}
我不知道有什么更好的方法来创建结构,但它是直接的,而且相当干净。
- 2 回答
- 0 关注
- 113 浏览
添加回答
举报