猿问

在 Golang 中查找模式的字节偏移量

我们可以通过“grep -ob模式文件名”找到文件中模式的字节偏移量;然而,grep并不utf8安全。如何在 Go 中找到模式的字节偏移量?该文件是进程日志,可以以TB为单位。


这就是我想要在 Go 中得到的:


$ cat fname

hello world

findme

hello 世界

findme again

...


$ grep -ob findme fname


12:findme

32:findme


缥缈止盈
浏览 137回答 1
1回答

元芳怎么了

FindAllStringIndex(s string, n int)返回表达式所有连续匹配的字节开始/结束索引(即切片):package mainimport "fmt"import "io/ioutil"import "regexp"func main() {    fname := "C:\\Users\\UserName\\go\\src\\so56798431\\fname"    b, err := ioutil.ReadFile(fname)    if err != nil {      panic(err)    }    re, err := regexp.Compile("findme")    if err != nil {      // handle error    }    fmt.Println(re.FindAllStringIndex(string(b), -1))}输出:[[12 18] [32 38]]注意:我在 Microsoft Windows 上执行此操作,但以 UNIX 格式(换行)保存文件;如果输入文件以 Windows 格式保存(回车和换行),则字节偏移量将分别增加到 13 和 35。更新:对于大文件,请使用bufio.Scanner;例如:package mainimport (    "bufio"    "fmt"    "log"    "os"    "regexp")func main() {    fname, err := os.Open("C:\\Users\\UserName\\go\\src\\so56798431\\fname")    if err != nil {        log.Fatal(err)    }    defer fname.Close()    re, err := regexp.Compile("findme")    if err != nil {      // handle error    }    scanner := bufio.NewScanner(fname)    bytesRead := 0    for scanner.Scan() {        b := scanner.Text()        //fmt.Println(b)        results := re.FindAllStringIndex(b, -1)        for _, result := range results {            fmt.Println(bytesRead + result[0])        }        // account for UNIX EOL marker        bytesRead += len(b) + 1    }    if err := scanner.Err(); err != nil {        log.Fatal(err)    }}输出:1232
随时随地看视频慕课网APP

相关分类

Go
我要回答