Golang執行個體001

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Part 01 目標

    對記錄檔進行過濾,拆分;

Part 02 瞭解與思路

    這是實習公司派給我的工作,在我快要淡出鳥的時候。有幾份記錄檔,很大的,以G為單位的。裡面很多不必要的資訊,需要過濾掉。另外,日誌是記錄在一起的,分析起來的時候,沒有條理性,所以,要求根據日期,進行拆分,同一天的日誌為一個檔案,以日期命名,檔案。
編程的重點是Regex的使用和檔案操作

Part 03 來幾行瞧瞧

    因為需要構造正則,所以得知道檔案的格式。直接開啟檔案是個不明智的選擇,對我而言,準確點,對我的電腦來說,開啟大檔案,我的小本本承受不了這樣的負擔。在Linux環境中,其實一條命令就可以了:

head -n 100 # 顯示前面100行;tail -n 100 # 顯示最後100行;sed -n '5,10p' filename # 這樣可以只查看檔案的第5行到第10行;

    是不是很方便。但是,我想練習一下golang,所以花了點時間,寫了個小程式:

// Auth:Reluxer// Time:2015-07-23// Name:preview.go// Description:閑得慌,寫了兩個函數package mainimport (    "bufio"    "fmt"    "io"    "os")const (    ViewLineNum = 40)func ReadFileByLine002(filename string) error {    f, err := os.OpenFile(filename, os.O_RDONLY, 0660)    if err != nil {        return err    }    defer f.Close()    sc := bufio.NewScanner(f)    for i := 0; i < ViewLineNum; i++ {        sc.Scan()        fmt.Println(sc.Text())    }    return sc.Err()}func ReadFileByLine001(filename string) error {    f, err := os.Open(filename)    if err != nil {        return err    }    defer f.Close()    buf := bufio.NewReader(f)    for i := 0; i < ViewLineNum; i++ {        line, err := buf.ReadString('\n')        if err != nil {            if err == io.EOF {                fmt.Println("EOF")                break            }            return err        }        fmt.Print(line)    }    return nil}func main() {    filename := os.Args[1]    err := ReadFileByLine002(filename)    if err != nil {        fmt.Println(err)    }}

    這樣之後,我看到了檔案的格式是這樣的:

10.88.111.101 - - [18/Jul/2015:00:00:02 +0800] "GET /topics/2014-11-18/2269791.html HTTP/1.1" 200 1557110.88.111.101 - - [18/Jul/2015:00:00:02 +0800] "GET /topics/2014-12-26/2419017.html HTTP/1.1" 200 1517610.88.111.101 - - [18/Jul/2015:00:00:03 +0800] "GET /topics/2012-10-18/3535945.html HTTP/1.1" 200 1525010.88.111.101 - - [18/Jul/2015:00:00:03 +0800] "GET /topics/2014-11-10/2245185.html HTTP/1.1" 200 15250

Part 04 過濾吧

    知道了檔案格式,接下來就是過濾掉冗雜的日誌,主要是.css,.js,.jpg,.png,.gif。這部分的代碼如下:

package mainimport (    "bufio"    "fmt"    "io"    "os"    "regexp")const (    RegRuler = `(\.js HTTP)|(\.jpg HTTP)|(\.png HTTP)|(\.css HTTP)|(\.gif HTTP)`)func Process(filesrc, fielestore string) error {    var fsrc, fdes *os.File    var err error    fsrc, err = os.OpenFile(filesrc, os.O_RDONLY, 0660)    if err != nil {        return err    }    defer fsrc.Close()    if fdes, err = os.OpenFile(fielestore, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666); err != nil {        return err    }    defer fdes.Close()    sc := bufio.NewScanner(fsrc)    reg := regexp.MustCompile(RegRuler)    for sc.Scan() {        line := sc.Text()        match := reg.FindString(line)        if match == "" {            if _, err = io.WriteString(fdes, line+"\n"); err != nil {                return err            }        }    }    return sc.Err()    return nil}func main() {    filename := os.Args[1]    filestorename := "no-css-jpg-png-gif-js_log"    if err := Process(filename, filestorename); err != nil {        fmt.Println(err)        return    }    fmt.Println("ok")}

    讓我沒想到的是,程式的已耗用時間超級長,長的我看了一集花千骨,它還沒結束。
    另外,這一步在Linux底下,也是敲一敲命令就完工的事情。Linux真是強大到沒邊了。

Part 05 拆分,時間是標準

    光是這樣,檔案還是太大,而且沒有條理,所以啊,要按照時間來拆分檔案。那好吧,你說拆分就拆分嘍,我沒意見。
    代碼如下:

package mainimport (    "bufio"    "fmt"    "io"    "os"    // "path"    "regexp")const (    RegRuler = `\[(?P<day>\d{2})/(?P<month>[A-Za-z]{3})/(?P<year>\d{4}):\d{2}:\d{2}:\d{2}\s\+\d{4}\]`)func Process(filesrc string) error {    var fsrc, fdes *os.File    var err error    premonth := ""    preday := ""    preyear := ""    curmonth := ""    curday := ""    curyear := ""    filedes := ""    fsrc, err = os.OpenFile(filesrc, os.O_RDONLY, 0660)    if err != nil {        return err    }    defer fsrc.Close()    sc := bufio.NewScanner(fsrc)    reg := regexp.MustCompile(RegRuler)    for sc.Scan() {        line := sc.Text()        // fmt.Println(line)        match := reg.FindStringSubmatch(line)        // fmt.Println(match)        // if match == nil {        //  if curday == "" && curmonth == "" && curyear == "" {        //      if fdes, err = os.OpenFile("unkonow.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err != nil {        //          return err        //      }        //  }        // fmt.Println("here")        // } else {        if match != nil {            for i, name := range reg.SubexpNames() {                //Ignore the whole regexp match and unnamed groups                if i == 0 || name == "" {                    continue                }                switch name {                case "month":                    curmonth = match[i]                case "day":                    curday = match[i]                case "year":                    curyear = match[i]                }            }            // fmt.Println(filedes)            if curday != preday || curmonth != premonth || curyear != preyear {                fdes.Close()                filedes = curyear + "-" + curmonth + "-" + curday                if fdes, err = os.OpenFile(filedes, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err != nil {                    return err                }            }        }        _, err = io.WriteString(fdes, line+"\n")        if err != nil {            // fmt.Println("here")            fdes.Close()            return err        }        preyear = curyear        preday = curday        premonth = curmonth        // match :=        //fmt.Fprintf(os.Stdout,"%s\n",scanner.Text())    }    fdes.Close()    return sc.Err()    return nil}func main() {    filename := os.Args[1]    // fmt.Println(filename)    // err := ReadFileByLine001(filename)    err := Process(filename)    if err != nil {        fmt.Println(err)    }    fmt.Println("ok")}

Part 06 結束吧

    到這兒呢,基本就差不多了。該結束了。說一下,感慨。

  • 之前的代碼少些了幾行,然後,我的小本本就承受不住,主板過熱,自動關機了,真的是嚇死爹了。
  • 編程的過程都是一邊百度,一邊碼代碼,也算是小有收穫。
  • 學語言就得實踐,在實踐中學習。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.