douhun8647 2018-08-27 03:57 采纳率: 0%
浏览 183
已采纳

解析io.ReadAll以匹配特定的表达式

I'm using the Golang Docker SDK to output container logs. The container is running a scan and outputs specific information about the scan job start time, end time, mean scan duration as below:

    Selected XML parser javax.xml.bind.util.JAXBSource$1 does not recognize the feature http://xml.org/sax/features/validation
    Generated ./reports/CSR1000V_RTR2.json
    Generated ./reports/CSR1000V_RTR6.json
    Generated ./reports/CSR1000V_RTR3.json
Scan start time: Mon Aug 27 03:39:24 GMT 2018
Scan end time:   Mon Aug 27 03:39:40 GMT 2018
Mean target scan duration: 3906ms

I use code below to convert the io.Reader into a string:

out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{
    ShowStdout: true,
    Follow:     true})
if err != nil {
    panic(err)
}
defer out.Close()
//io.Copy(os.Stdout, out)
b, err := ioutil.ReadAll(out)

fmt.Println(string(b))

How in Golang can I parse only the last 3 lines and capture the following values only from the stdout:

fmt.Println("The scan has started at: " +startime)
fmt.Println("The scan has ended at: " +endtime)
fmt.Println("The scan job took xxx ms to scan each device")
  • 写回答

2条回答 默认 最新

  • doubi4814 2018-08-27 17:48
    关注

    An alternative solution is to use the bufio.Scanner api.

    It might be interesting if you are dealing with large output that you don t want to store full in memory for processing.

    The scanner is a composition of a reader, the input data, and a split function, to creates meaningful chunks of data.

    Using the standard api it is possible to take advantage of the provided bufio.ScanLines function to split the output by lines, then a simple prefix equality will yield the necessary information to identify the researched information.

    package main
    
    import (
        "bufio"
        "bytes"
        "fmt"
        "strings"
    )
    
    type result struct {
        start string
        end   string
        mean  string
    }
    
    func main() {
        raw := `
        Selected XML parser javax.xml.bind.util.JAXBSource$1 does not recognize the feature http://xml.org/sax/features/validation
        Generated ./reports/CSR1000V_RTR2.json
        Generated ./reports/CSR1000V_RTR6.json
        Generated ./reports/CSR1000V_RTR3.json
    Scan start time: Mon Aug 27 03:39:24 GMT 2018
    Scan end time:   Mon Aug 27 03:39:40 GMT 2018
    Mean target scan duration: 3906ms
    `
        scanner := bufio.NewScanner(strings.NewReader(raw))
    
        var res result
        // Create a custom split function by wrapping the existing ScanLines function.
        split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
            advance, token, err = bufio.ScanLines(data, atEOF)
            if err == nil && token != nil {
                if pattern := []byte("Scan start time:"); bytes.HasPrefix(token, pattern) {
                    res.start = strings.TrimSpace(string(token[len(pattern):]))
                } else if pattern := []byte("Scan end time:"); bytes.HasPrefix(token, pattern) {
                    res.end = strings.TrimSpace(string(token[len(pattern):]))
                } else if pattern := []byte("Mean target scan duration:"); bytes.HasPrefix(token, pattern) {
                    res.mean = strings.TrimSpace(string(token[len(pattern):]))
                }
            }
            return
        }
        // Set the split function for the scanning operation.
        scanner.Split(split)
        // drain the source
        for scanner.Scan() {
        }
    
        if err := scanner.Err(); err != nil {
            fmt.Printf("Invalid input: %s", err)
        }
        fmt.Printf("%#v
    ", res)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵