隔离字符串输出

时间:2018-01-31 21:21:55

标签: string go

我目前有一个执行os命令的脚本,它返回大量数据,在数据末尾它总共得到:

N总计。

N可以是从0开始的任何数字。

我想执行此命令,然后取N然后将其放入值中。我已经运行了命令并且我将它存储在一个bytes.Buffer中,但是我不确定如何刮掉它以便我只得到这个数字。 " N总计。" string始终位于输出的末尾。任何帮助都会受到赞赏,因为我已经看到了各种不同的方法,但它们看起来都很复杂。

2 个答案:

答案 0 :(得分:0)

您可以将字符串拆分为\n并获取最后一行。

package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() {
    output := `
Some os output
Some more os output
Again some os output
1001 Total`

    // If you're getting the string from the bytes.Buffer do this:
    // output := myBytesBuffer.String()

    outputSplit := strings.Split(output, "\n") // Break into lines

    // Get last line from the end.
    // -1 assumes the numbers in the last line. Change it if its not.
    lastLine := outputSplit[len(outputSplit)-1]

    lastLine = strings.Replace(lastLine, " Total", "", -1) // Remove text

    number, _ := strconv.Atoi(lastLine) // Convert from text to number

    fmt.Println(number)
}

peterSO指出,对于大输出,上述情况可能会很慢。

这是使用已编译的regexp表达式匹配一小部分字节的另一种方法。

package main

import (
    "bytes"
    "fmt"
    "os/exec"
    "regexp"
    "strconv"
)

func main() {
    // Create regular expression. You only create this once.
    // Would be regexpNumber := regexp.MustCompile(`(\d+) Total`) for you
    regexpNumber := regexp.MustCompile(`(\d+) bits physical`)

    // Whatever your os command is
    command := exec.Command("cat", "/proc/cpuinfo")
    output, _ := command.Output()

    // Your bytes.Buffer
    var b bytes.Buffer
    b.Write(output)

    // Get end of bytes slice
    var end []byte
    if b.Len()-200 > 0 {
        end = b.Bytes()[b.Len()-200:]
    } else {
        end = b.Bytes()
    }

    // Get matches. matches[1] contains your number
    matches := regexpNumber.FindSubmatch(end)

    // Convert bytes to int
    number, _ := strconv.Atoi(string(matches[1])) // Convert from text to number
    fmt.Println(number)
}

答案 1 :(得分:0)

您可以使用bufio.Scanner逐行读取命令的输出。然后记住最后一行,并在命令完成后解析它。

package main

import (
    "bufio"
    "fmt"
    "io"
    "os/exec"
    "strings"
)

func main() {
    r, w := io.Pipe()

    cmd := exec.Command("fortune")
    cmd.Stdout = w
    go func() {
            cmd.Run()
            r.Close()
            w.Close()
    }()

    sc := bufio.NewScanner(r)
    var lastLine string
    for sc.Scan() {
            line := sc.Text()
            fmt.Println("debug:", line)

            if strings.TrimSpace(line) != "" {
                    lastLine = line
            }
    }

    fmt.Println(lastLine)
}

示例输出:

debug: "Get back to your stations!"
debug: "We're beaming down to the planet, sir."
debug: -- Kirk and Mr. Leslie, "This Side of Paradise",
debug: stardate 3417.3
stardate 3417.3

解析lastLine是留给读者的练习。

相关问题