Go:处理多行命令输出并解析

huangapple go评论87阅读模式
英文:

Go: Process multi-line command output and parse

问题

我正在尝试从命令行实用程序中提取信息,这里是Linux的ntpq -c rv命令。

输出:

associd=0 status=0638 leap_none, sync_ntp, 3 events, no_sys_peer,
version="ntpd 4.2.6p5@1.2349-o Fri Jul 22 17:30:51 UTC 2016 (1)",
processor="x86_64", system="Linux/3.16.0-4-amd64", leap=00, stratum=2,
precision=-22, rootdelay=25.435, rootdisp=49.398, 
refid=8.8.8.8,
reftime=dd64d70e.3edbe503  Thu, Sep 14 2017 12:23:10.245,
clock=dd64dbaa.ded8fa8e  Thu, Sep 14 2017 12:42:50.870, peer=51954,
tc=10, mintc=3, offset=1.941, frequency=3.236, sys_jitter=0.869,
clk_jitter=0.413, clk_wander=0.068

我需要从中获取的是:stratum和offset。

我已经编写了这段代码:

if Exists("/usr/bin/ntpq") {
  cmd := exec.Command("ntpq","-c rv")
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error creating StdoutPipe", err)
		os.Exit(1)
	}
	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			fmt.Printf("out %s\n", scanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
		os.Exit(1)
	}

	err = cmd.Wait()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error waiting for Cmd", err)
		os.Exit(1)
	}
} 

我能够逐行获取命令的输出,但我不确定如何提取我想要的信息。有人可以帮助我吗?

英文:

I am trying to extract information from a command line utility, in this case the linux ntpq -c rv command.

Output:

associd=0 status=0638 leap_none, sync_ntp, 3 events, no_sys_peer,
version="ntpd 4.2.6p5@1.2349-o Fri Jul 22 17:30:51 UTC 2016 (1)",
processor="x86_64", system="Linux/3.16.0-4-amd64", leap=00, stratum=2,
precision=-22, rootdelay=25.435, rootdisp=49.398, 
refid=8.8.8.8,
reftime=dd64d70e.3edbe503  Thu, Sep 14 2017 12:23:10.245,
clock=dd64dbaa.ded8fa8e  Thu, Sep 14 2017 12:42:50.870, peer=51954,
tc=10, mintc=3, offset=1.941, frequency=3.236, sys_jitter=0.869,
clk_jitter=0.413, clk_wander=0.068

What i need out of this is: stratum and offset.

I have built this piece of code:

if Exists("/usr/bin/ntpq") {
  cmd := exec.Command("ntpq","-c rv")
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error creating StdoutPipe", err)
		os.Exit(1)
	}
	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			fmt.Printf("out %s\n", scanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
		os.Exit(1)
	}

	err = cmd.Wait()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error waiting for Cmd", err)
		os.Exit(1)
	}
} 

I am able to get the output from the command, line by line but i am unsure on how to extract only the information i want.
Can anyone help me with this?

答案1

得分: 2

使用正则表达式将数据提取出来,并将其解析为整数和浮点数值。

package main

import (
	"fmt"
	"regexp"
	"strconv"
)

func main() {
	// 期望的输出
	output := `associd=0 status=0638 leap_none, sync_ntp, 3 events, no_sys_peer,
version="ntpd 4.2.6p5@1.2349-o Fri Jul 22 17:30:51 UTC 2016 (1)",
processor="x86_64", system="Linux/3.16.0-4-amd64", leap=00, stratum=2,
precision=-22, rootdelay=25.435, rootdisp=49.398, 
refid=8.8.8.8,
reftime=dd64d70e.3edbe503  Thu, Sep 14 2017 12:23:10.245,
clock=dd64dbaa.ded8fa8e  Thu, Sep 14 2017 12:42:50.870, peer=51954,
tc=10, mintc=3, offset=1.941, frequency=3.236, sys_jitter=0.869,
clk_jitter=0.413, clk_wander=0.068`

	// 尝试查找 stratum
	match := regexp.MustCompile("stratum=(\\d+),").FindStringSubmatch(output)
	stratum := 0
	if match != nil {
		if i, err := strconv.Atoi(match[1]); err == nil {
			stratum = i
		}
	}

	// 尝试查找 offset
	match = regexp.MustCompile("offset=(\\d+\\.\\d+),").FindStringSubmatch(output)
	offset := 0.0
	if match != nil {
		if f, err := strconv.ParseFloat(match[1], 64); err == nil {
			offset = f
		}
	}

	fmt.Println(stratum)
	fmt.Println(offset)
}
英文:

Use Regular Expression to get the data and parse it into int, and float values.

> https://play.golang.org/p/vDx8dw4Mpo

package main

import (
	"fmt"
	"regexp"
	"strconv"
)

func main() {
	// Expected output
	output := `associd=0 status=0638 leap_none, sync_ntp, 3 events, no_sys_peer,
version="ntpd 4.2.6p5@1.2349-o Fri Jul 22 17:30:51 UTC 2016 (1)",
processor="x86_64", system="Linux/3.16.0-4-amd64", leap=00, stratum=2,
precision=-22, rootdelay=25.435, rootdisp=49.398, 
refid=8.8.8.8,
reftime=dd64d70e.3edbe503  Thu, Sep 14 2017 12:23:10.245,
clock=dd64dbaa.ded8fa8e  Thu, Sep 14 2017 12:42:50.870, peer=51954,
tc=10, mintc=3, offset=1.941, frequency=3.236, sys_jitter=0.869,
clk_jitter=0.413, clk_wander=0.068`

	// Try to find stratum
	match :=  regexp.MustCompile("stratum=(\\d+),").FindStringSubmatch(output)
	stratum := 0
    if (match != nil) {
		if i, err := strconv.Atoi(match[1]); err == nil {
			stratum = i
		}
	}

	// Try to find offset
	match =  regexp.MustCompile("offset=(\\d+\\.\\d+),").FindStringSubmatch(output)
	offset := 0.0
    if (match != nil) {
		if f, err := strconv.ParseFloat(match[1], 64); err == nil {
			offset = f
		}
	}

	fmt.Println(stratum)
	fmt.Println(offset)
}

huangapple
  • 本文由 发表于 2017年9月14日 18:46:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/46217032.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定