go语言四——脚本一

ciaos · · 4778 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

工作中用go语言写了点脚本代替python的功能,涉及文件读写,记录如下

package main

import (
        "os"
        "os/exec"
        "log"
        "bytes"
        "strings"
        "bufio" //文件读写
        "strconv"
//      "fmt"
)

const pwd = "/usr/local/nginx/htdocs/"

func get_logname(ziplog_name string) (string) {

        var out bytes.Buffer
 
        //hint:用exec.Command获取一个Cmd对象,设置标准输出到out,执行Run操作
        cmd := exec.Command("unzip","-o",ziplog_name,"-d",ziplog_name[0:len(ziplog_name)-4])
        cmd.Stdout = &out
        err := cmd.Run()
        if err != nil {
                log.Fatal(err)
        }
        //hint:标准输出可通过out.String()获取,用strings.Index获取指定字符串所在位置
        i:=strings.Index(out.String(),"inflating: ")
        log_name:=out.String()[i+len("inflating: "):]
        //hint:通过strings.Trim删除字符串两侧的换行符以及空格
        log_name = strings.Trim(log_name,"\n ")

        return log_name
}

func getinfo(line string)(string,string,string) {
        appname, day, curhour := "", "", ""

        //用strings的库函数拆分字符串,可以用&&添加多个判断
        if info := strings.Split(line, " "); len(info) > 5 && info[3] == "OK" {
                appname = info[4]
        }
        if tday := strings.Split(line, "["); len(tday) > 1 {
                tday = strings.Split(tday[1]," ")

                day = ...
        }

        if hour := strings.Split(line, ":"); len(hour) > 1 {
                //hint 用strconv库函数判断字符串是否为数字
                _, err := strconv.Atoi(hour[1])
                if err != nil {
                        return "","",""
                }
                curhour = hour[1]

        }
        return appname, day, curhour
}

func saveline(filepath, filename, line string) {

        //打开文件,如果失败,创建文件夹先,打开方式为append,和读写
        f, err := os.OpenFile(filename, os.O_APPEND|os.O_RDWR, 0666)
        if err != nil {
                //如果文件夹已经创建,返回nil,MkdirAll是递归创建子目录
                err = os.MkdirAll(filepath, 0755)
                if err != nil {
                        log.Fatal(err)
                }
                f, err = os.OpenFile(filename, os.O_APPEND|os.O_RDWR, 0666)
                if err != nil {
                        //如果文件不存在,则用Create创建,默认打开类型为读写
                        f, err = os.Create(filename)
                        if err != nil {
                                log.Fatal(err)
                        }
                }
        }

        //设置defer关闭文件
        defer f.Close()

        //hint:用bufio逐行写入文件
        line = line + "\n"
        b := bufio.NewWriter(f)
        if n, err := b.WriteString(line); err != nil || n != len(line) {
                log.Fatal(err)
        }
        //hint:调用Flush将内存写到磁盘
        if err = b.Flush(); err != nil {
                log.Fatal(err)
        }
}

func worker(line, p1, p2 string) {
        app, day, hour := getinfo(line)

        var filepath, filename string

        if day == "" || hour == "" {
                return
        }

        if app != "" {
                filepath = pwd + "workdir/app/" +  app + "/" + day + "/"
                filename = filepath + hour + ".log"
                saveline(filepath, filename, line)
        }

        filepath = pwd + "workdir/backup/" + day + "/" + log_from + "/"
        filename = filepath + hour + ".log"
        saveline(filepath, filename, line)
}

func main() {

        //hint :os.Args获取命令行参数,用len获取参数个数
        if len(os.Args) < 3 {
                log.Panic("fatal error")
        }
        para1, para2 := os.Args[1], os.Args[2]

        //hint :调用os的函数Chdir实现目录切换
        if err := os.Chdir(pwd + "workdir/"); err != nil {
                log.Panic("fatal error")
        }

        //hint :设置defer,函数退出时调用os.RemoveAll,递归删除子目录以及文件
        defer os.RemoveAll("dir")
        defer f.Close()

        //hint :用os.Open打开文件以及bufio逐行读取
        f, err := os.Open("file.exist")
        if err != nil {
                log.Fatal(err)
        }

        r := bufio.NewReader(f)
        line, _, err := r.ReadLine()
        for err == nil {
                worker(string(line),para1,para2)
                line, _, err = r.ReadLine()
        }
}

日志记录到文件的方法如下:

 

package main

import "io"
import "log"
import "os"

const logFileName = "test.log"

func main() {
        logf, err := os.OpenFile(logFileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0640)
        if err != nil {
                log.Fatalln(err)
        }
        log.SetOutput(logf)
        mylogger := log.New(io.MultiWriter(logf,os.Stdout),"",-1)
        log.Println("goes to logf")
        mylogger.Println("goes to stdout and logf")
}

日志文本如下

2013/06/04 07:59:06 goes to logf
2013/06/04 07:59:06.526852 test.go:17: goes to stdout and logf

不知道如何做性能对比,不过从运行结果来看,cpu占用比python低非常多


有疑问加站长微信联系(非本文作者)

本文来自:ITEYE博客

感谢作者:ciaos

查看原文:go语言四——脚本一

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4778 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传