Windows下面替换命令实现,最新修复一个BUG

package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var (
	dir     string
	file    string
	oldstr  string
	newstr  string
	Reg     *regexp.Regexp
	Err     error
	test    bool
	readall bool
)

func main() {
	flag.StringVar(&dir, "d", "./", "-d directory")
	flag.StringVar(&file, "f", "", "-f *.ini")
	flag.StringVar(&oldstr, "s", "", "-s oldstr")
	flag.StringVar(&newstr, "r", "", "-r newstr")
	flag.BoolVar(&test, "t", false, "-t true")
	flag.BoolVar(&readall, "a", false, "-a true")
	flag.Parse()

	if file == "" {
		fmt.Printf("Args Error: %s must not null\n", "-f")
		return
	}

	if oldstr == "" || newstr == "" {
		if !test {
			fmt.Printf("Args Error: %s and %s must not null.\n\n", "-s", "-r")
			flag.Usage()
			return
		}
	}

	if strings.Index(file, "*") == 0 {
		file = "." + file
	} else {
		file = "^" + file
	}
	file += "$"

	Reg, Err = regexp.Compile(file)
	if Err != nil {
		fmt.Printf("Regexp string error.\nError info: %s\n", Err)
		return
	}
	err := filepath.Walk(dir, walk)
	if err != nil {
		fmt.Println(err)
	}
}

func walk(root string, info os.FileInfo, err error) error {
	root = filepath.ToSlash(root)
	if err != nil {
		return err
	}
	if info.IsDir() || !Reg.MatchString(info.Name()) {
		return nil
	}
	if test {
		fmt.Println(root)
		return nil
	}
	if readall {
		ReadAll(root)
	} else {
		path := filepath.Dir(root) + "/." + filepath.Base(root)
		tmp := fmt.Sprintf("%s.tmp", path)
		if err := ReadLine(root, tmp); err != nil {
			return nil
		}
		os.Remove(root)
		os.Rename(tmp, root)
	}
	return nil
}

func ReadLine(root, tmp string) error {
	File, err := os.Open(root)
	if err != nil {
		fmt.Printf("Open file %s faild.\nError Info: %s\n", root, err)
		return err
	}
	defer File.Close()
	tmpFile, err := os.Create(tmp)
	if err != nil {
		fmt.Printf("Create temporary files for %s faild.\nError info %s\n", root, err)
		return err
	}
	defer tmpFile.Close()
	buf := bufio.NewReader(File)
	var num int = 0
	for {
		line, err := buf.ReadSlice('\n')
		num += bytes.Count(line, []byte(oldstr))
		if err != nil {
			if err.Error() == "EOF" {
				line = bytes.Replace(line, []byte(oldstr), []byte(newstr), -1)
				tmpFile.Write(line)
				break
			}
			fmt.Printf("Read %s error.\nError Info: %s\n", root, err)
			return nil
		}
		line = bytes.Replace(line, []byte(oldstr), []byte(newstr), -1)
		tmpFile.Write(line)
	}
	if num > 0 {
		fmt.Printf("File: %s Replace: %d\n", root, num)
	}
	return nil
}

func ReadAll(root string) {
	body, err := ioutil.ReadFile(root)
	if err != nil {
		fmt.Printf("Read file %s faild.\nError Info: %s\n", root, err)
		return
	}
	num := bytes.Count(body, []byte(oldstr))
	body = bytes.Replace(body, []byte(oldstr), []byte(newstr), -1)
	File, err := os.Create(root)
	if err != nil {
		fmt.Printf("Create replace file %s faild.\nError Info: %s\n", root, err)
		return
	}
	defer File.Close()
	File.Write(body)
	if num > 0 {
		fmt.Printf("File: %s Replace: %d\n", root, num)
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值