英文:
Trying to parse a stdout on command line with Golang
问题
我正在练习使用Go语言将参数传递给命令行,并能够解析传递出来的结果信息。例如,我有一段代码用于执行命令,并显示通过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
我的问题是:如果我想解析平均响应时间,以便将其赋值给一个变量,以便在需要时显示它,我该如何解析它?
英文:
I'm practicing to use GoLang to pass arguements to the command line, and being able to parse information from the results that are passed out. For example, I have code that is designed to execute a command, and display what will display anyway if the command was entered through cmd anyway.
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))
}
}
Considering the output would be:
==> 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
My question is: If I wanted to parse the Average response time, so I can assign that to a variable so I can display that when I want to, how can I parse that?
答案1
得分: 6
你可以使用regexp
来实现。例如,像这样的代码:
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 版本
//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("==> 执行命令: %s\n", strings.Join(cmd.Args, " "))
}
func printError(err error) {
if err != nil {
os.Stderr.WriteString(fmt.Sprintf("==> 错误: %s\n", err.Error()))
}
}
func printOutput(outs []byte) {
if len(outs) > 0 {
fmt.Printf("==> 输出: %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 版本
/*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")
}*/
}
这段代码使用了regexp
包来解析命令行输出中的平均时间。你可以根据需要进行修改和使用。
英文:
You can use regexp
. For instance something like:
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")
}*/
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论