亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

GO中日志文件的文本解析

GO中日志文件的文本解析

Go
慕標琳琳 2023-07-26 17:19:39
新手來這里吧!我正在嘗試編寫一個 Go 程序,該程序將解析日志文件并返回匹配行的特定信息。為了舉例說明我想要實現的目標,我將從一個如下所示的日志文件開始:2019-09-30T04:17:02 - REQUEST-A2019-09-30T04:18:02 - REQUEST-C2019-09-30T04:19:02 - REQUEST-B2019-09-30T04:20:02 - REQUEST-A2019-09-30T04:21:02 - REQUEST-A2019-09-30T04:22:02 - REQUEST-B從這里我想提取所有“REQUEST-A”并將請求發生的時間打印到終端或文件。我嘗試過使用 os.Open 和 Scanner,并且可以使用 Scanner.Text 來記錄它已發現我的字符串的出現,如下所示:package mainimport (    "bufio"    "fmt"    "os"    "strings")func main() {    request := 0    f, err := os.Open("request.log")    if err != nil {        fmt.Print("There has been an error!: ", err)    }    defer f.Close()    scanner := bufio.NewScanner(f)    for scanner.Scan() {        if strings.Contains(scanner.Text(), "REQUEST-A") {            request = request + 1        }        if err := scanner.Err(); err != nil {        }        fmt.Println(request)    }}但我不確定如何用它來檢索我想要的信息。通常我會使用 Bash,但我想我應該擴展一下,看看是否可以使用 Go。任何建議將不勝感激。
查看完整描述

3 回答

?
翻過高山走不出你

TA貢獻1875條經驗 獲得超3個贊

在 Go 中,我們努力提高效率。不要做不必要的事情。


例如,


package main


import (

    "bufio"

    "bytes"

    "fmt"

    "os"

)


func main() {

    lines, requestA := 0, 0

    f, err := os.Open("request.log")

    if err != nil {

        fmt.Print("There has been an error!: ", err)

    }

    defer f.Close()


    scanner := bufio.NewScanner(f)

    for scanner.Scan() {

        lines++

        // filter request a

        line := scanner.Bytes()

        if len(line) <= 30 || line[30] != 'A' {

            continue

        }

        if !bytes.Equal(line[22:], []byte("REQUEST-A")) {

            continue

        }

        requestA++

        request := string(line)


        // handle request a

        fmt.Println(request)

    }

    if err := scanner.Err(); err != nil {

        fmt.Println(err)

    }

    fmt.Println(lines, requestA)

}

輸出:


$ go run request.go


2019-09-30T04:17:02 - REQUEST-A

2019-09-30T04:20:02 - REQUEST-A

2019-09-30T04:21:02 - REQUEST-A

6 3


$ cat request.log

2019-09-30T04:17:02 - REQUEST-A

2019-09-30T04:18:02 - REQUEST-C

2019-09-30T04:19:02 - REQUEST-B

2019-09-30T04:20:02 - REQUEST-A

2019-09-30T04:21:02 - REQUEST-A

2019-09-30T04:22:02 - REQUEST-B

為了強調效率的重要性(日志可能非常大),讓我們針對Markus W Mahlberg的解決方案運行一個基準測試:https://play.golang.org/p/R2D_BeiJvx9。


$ go test log_test.go -bench=. -benchmem

BenchmarkPeterSO-4   21285     56953 ns/op    4128 B/op      2 allocs/op

BenchmarkMarkusM-4     649   1817868 ns/op   84747 B/op   2390 allocs/op

log_test.go:


package main


import (

    "bufio"

    "bytes"

    "regexp"

    "strings"

    "testing"

)


var requestLog = `

2019-09-30T04:17:02 - REQUEST-A

2019-09-30T04:18:02 - REQUEST-C

2019-09-30T04:19:02 - REQUEST-B

2019-09-30T04:20:02 - REQUEST-A

2019-09-30T04:21:02 - REQUEST-A

2019-09-30T04:22:02 - REQUEST-B

`


var benchLog = strings.Repeat(requestLog[1:], 256)


func BenchmarkPeterSO(b *testing.B) {

    for N := 0; N < b.N; N++ {

        scanner := bufio.NewScanner(strings.NewReader(benchLog))

        for scanner.Scan() {

            // filter request a

            line := scanner.Bytes()

            if len(line) <= 30 || line[30] != 'A' {

                continue

            }

            if !bytes.Equal(line[22:], []byte("REQUEST-A")) {

                continue

            }

            request := string(line)

            // handle request a

            _ = request

        }

        if err := scanner.Err(); err != nil {

            b.Fatal(err)

        }

    }

}


func BenchmarkMarkusM(b *testing.B) {

    for N := 0; N < b.N; N++ {

        var re *regexp.Regexp = regexp.MustCompile(`^(\S*) - REQUEST-A$`)

        scanner := bufio.NewScanner(strings.NewReader(benchLog))

        var res []string

        for scanner.Scan() {

            if res = re.FindStringSubmatch(scanner.Text()); len(res) > 0 {

                _ = res[1]

            }

        }

        if err := scanner.Err(); err != nil {

            b.Fatal(err)

        }

    }

}



查看完整回答
反對 回復 2023-07-26
?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

使用以下代碼打印值為“REQUEST-A”的日志條目的時間字段。


for scanner.Scan() {

    line := scanner.Text()

    if len(line) < 19 {

        continue

    }

    if line[19:] == " - REQUEST-A" {

        fmt.Println(line[:19])

    }

}

在圍棋游樂場上運行它!

要寫入文件,請將 stdout 重定向到文件。


上面的代碼假設時間戳之后的所有內容都是“-REQUEST-A”。如果“-REQUEST-A”是其他數據的前綴,請使用以下內容:


const lenTimestamp = 19

for scanner.Scan() {

    line := scanner.Text()

    if len(line) < lenTimestamp {

        continue

    }

    if strings.HasPrefix(line[lenTimestamp:], " - REQUEST-A") {

        fmt.Println(line[:lenTimestamp])

    }

}

在操場上運行這個版本。



查看完整回答
反對 回復 2023-07-26
?
函數式編程

TA貢獻1807條經驗 獲得超9個贊

如果您使用的是 Linux 或 Mac,則不需要 Go 程序:


$ echo "2019-09-30T04:17:02 - REQUEST-A

2019-09-30T04:18:02 - REQUEST-C

2019-09-30T04:19:02 - REQUEST-B

2019-09-30T04:20:02 - REQUEST-A

2019-09-30T04:21:02 - REQUEST-A

2019-09-30T04:22:02 - REQUEST-B" | awk '/REQUEST-A/{print $1}' | tee request.log

2019-09-30T04:17:02

2019-09-30T04:20:02

2019-09-30T04:21:02

然而,如果你真的想在 Go 中實現這個:


package main


import (

    "bufio"

    "fmt"

    "regexp"

    "strings"

)


const input = `

2019-09-30T04:17:02 - REQUEST-A

2019-09-30T04:18:02 - REQUEST-C

2019-09-30T04:19:02 - REQUEST-B

2019-09-30T04:20:02 - REQUEST-A

2019-09-30T04:21:02 - REQUEST-A

2019-09-30T04:22:02 - REQUEST-B

`


var scanner = bufio.NewScanner(strings.NewReader(input))


// Here comes the magic: We create an anonymous group containing all

// non-whitespace characters up to the first blank. Since it is

// a group, we can easily extract it later down the road.

var re *regexp.Regexp = regexp.MustCompile(`^(\S*) - REQUEST-A$`)


func main() {

    var res []string

    for scanner.Scan() {

        // We use re.FindStringSubmatch here, as it actually kills two

        // birds with one stone: We check wether it is REQUEST-A

        // and the anonymous group of the regexp contains what we are looking for.

        if res = re.FindStringSubmatch(scanner.Text()); len(res) > 0 {

            fmt.Println(res[1])

        }

    }

}

Run on playground



查看完整回答
反對 回復 2023-07-26
  • 3 回答
  • 0 關注
  • 179 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號