parsing - 尝试使用 Golang 在命令行上解析标准输出

标签 parsing go command-line

我正在练习使用 GoLang 将参数传递给命令行,并能够从传递的结果中解析信息。例如,我的代码旨在执行命令,并显示如果通过 cmd 输入命令无论如何都会显示的内容。

package main

import (
    "bytes"
    "fmt"
    "os"
    "os/exec"
    "strings"
)

func main() {
    cmd = exec.Command("ping", "8.8.8.8")
    cmdOutput = &bytes.Buffer{}
    cmd.Stdout = cmdOutput
    printCommand(cmd)
    err = cmd.Run()
    printError(err)
    printOutput(cmdOutput.Bytes())
}

func printCommand(cmd *exec.Cmd) {
    fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " "))
}

func printError(err error) {
    if err != nil {
        os.Stderr.WriteString(fmt.Sprintf("==> Error: %s\n", err.Error()))
    }
}

func printOutput(outs []byte) {
    if len(outs) > 0 {
        fmt.Printf("==> Output: %s\n", string(outs))
    }
}

考虑输出将是:

==> Executing: ping 8.8.8.8
==> Output:
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=13ms TTL=56
Reply from 8.8.8.8: bytes=32 time=13ms TTL=56
Reply from 8.8.8.8: bytes=32 time=14ms TTL=56
Reply from 8.8.8.8: bytes=32 time=11ms TTL=56

Ping statistics for 8.8.8.8:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% lo
Approximate round trip times in milli-seconds:
    Minimum = 11ms, Maximum = 14ms, Average = 12ms

我的问题是:如果我想解析平均响应时间,那么我可以将它分配给一个变量,这样我就可以在需要时显示它,我该如何解析它?

最佳答案

您可以使用正则表达式。例如:

package main

import (
        "bytes"
        "fmt"
        "os"
        "os/exec"
        "regexp"
        "strings"
        "time"
)

type Ping struct {
        average time.Duration
}

func main() {
        cmd := exec.Command("ping", "8.8.8.8")
        // Linux version
        //cmd := exec.Command("ping", "-c 4", "8.8.8.8")
        cmdOutput := &bytes.Buffer{}
        cmd.Stdout = cmdOutput
        printCommand(cmd)
        err := cmd.Run()
        printError(err)
        output := cmdOutput.Bytes()
        printOutput(output)
        ping := Ping{}
        parseOutput(output, &ping)

        fmt.Println(ping)
}

func printCommand(cmd *exec.Cmd) {
        fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " "))
}

func printError(err error) {
        if err != nil {
                os.Stderr.WriteString(fmt.Sprintf("==> Error: %s\n", err.Error()))
        }
}

func printOutput(outs []byte) {
        if len(outs) > 0 {
                fmt.Printf("==> Output: %s\n", string(outs))
        }
}

func parseOutput(outs []byte, ping *Ping) {
        var average = regexp.MustCompile(`Average = (\d+ms)`)
        result := average.FindStringSubmatch(string(outs))

        if len(result) > 0 {
                ping.average, _ = time.ParseDuration(result[1])
        }
        // Linux version
        /*var average = regexp.MustCompile(`min\/avg\/max\/mdev = (0\.\d+)\/(0\.\d+)\/(0\.\d+)\/(0\.\d+) ms`)
        result := average.FindAllStringSubmatch(string(outs), -1)

        if len(result) > 0 {
                ping.average, _ = time.ParseDuration(result[0][2] + "ms")
        }*/
}

关于parsing - 尝试使用 Golang 在命令行上解析标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42213996/

相关文章:

xml - 从维基百科页面获取 xml

macos - Goland 在调试时不接受标准输入

c++ - gcc 指定任何软件异常的命令行选项可能会保留使用 'throw()' 声明的函数

mongodb - golang mongodb (mgo) 没有插入文档

Golang grpc go.mod 问题

python - 文本输入和服务器之间的接口(interface),用于使用该文本执行命令行应用程序

C# 服务器自定义命令行界面

bash - 在 Bash 中转置文件的有效方法

parsing - 将 Lemon 解析器与自定义标记值一起使用

使用 OperatorPrecedenceParser 使用 FParsec 解析函数应用程序?