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

解析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 centos7.9 IPv6端口telnet和端口监控问题
  • ¥120 计算机网络的新校区组网设计
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单