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 商城生产日期批次库存问题
  • ¥15 esp8266控制共阳极wrgb灯板无法关闭所有led灯
  • ¥100 python读取速度问题
  • ¥15 stm32f407使用DMA问题
  • ¥15 您好 这个API接口该怎么弄 网站搭建好了 API也有 现在就不知道该怎么填写API 不知道怎么用
  • ¥88 用uniapp写一个多端的程序,用到高德地图,用高德的JSAPI吗?
  • ¥20 关于#c++#的问题:水果店管理系统
  • ¥30 dbLinq最新版linq sqlite
  • ¥20 对D盘进行分盘之前没有将visual studio2022卸载掉,现在该如何下载回来
  • ¥15 完成虚拟机环境配置,还有安装kettle