批量替换和转移目录的东东

来源:转载

     拷,1点半了,写太晚了。 总之是个好东东。直接上代码了,不解释。

/*批量替换和转移目录的东东 遍历指定目录(包含子目录),对于指定扩展名的文件, 查找并替换文件内容中的指定字符串,并 将其输出到新的目录(包含子目录)下。原文件内容不变。 至于其它非指定的文件,也一并复制一份到新目录下。 使用Josn作为配置文件.Author:XiongChuanLiangDate:2015-10-23Linux 配置示例: {"sourcedir":"/home/xcl/test/t1/","destdir":"/home/xcl/test/t2/","fileext":[".go",".conf"],"replacewhere":[{ "findwhat":"V9", "replacewith":"V10" }, { "findwhat":"172.18.1.101", "replacewith":"192.168.1.101" }]}注意: sourcedir与destdir 配置时要对整齐,且最后要加"/".*/package mainimport ( "bufio" "encoding/json" "fmt" "io" "io/ioutil" "os" "path/filepath" "runtime" "strings" "sync" "time")const ( flagFile = "flag.json")type RWhere struct { FindWhat string `json:"findwhat"` ReplaceWith string `json:"replacewith"`}type ReplaceConf struct { SourceDir string `json:"sourcedir"` DestDir string `json:"destdir"` FileExtension []string `json:"fileext"` ReplaceWhere []RWhere `json:"replacewhere"` CaseSensitive bool `json:"casesensitive,omitempty"`}var repConf ReplaceConfvar repReplacer *strings.Replacervar extFileNum, otherFileNum intvar maxGoroutines intfunc init() { maxGoroutines = 10}func main() { now := time.Now() runtime.GOMAXPROCS(runtime.NumCPU()) parseJsonFile() findSourceFiles(repConf.SourceDir) end_time := time.Now() var dur_time time.Duration = end_time.Sub(now) fmt.Printf("elapsed %f seconds/n", dur_time.Seconds()) fmt.Println("处理统计") fmt.Println(" 处理指定类型文件:", extFileNum) fmt.Println(" 处理其它文件:", otherFileNum)}func findSourceFiles(dirname string) { waiter := &sync.WaitGroup{} fmt.Println("dirname:", dirname) filepath.Walk(dirname, sourceWalkFunc(waiter)) waiter.Wait()}func sourceWalkFunc(waiter *sync.WaitGroup) func(string, os.FileInfo, error) error { return func(path string, info os.FileInfo, err error) error { if err == nil && info.Size() > 0 && !info.IsDir() { if runtime.NumGoroutine() > maxGoroutines { parseFile(path, nil) } else { waiter.Add(1) go parseFile(path, func() { waiter.Done() }) } } else { fmt.Println("[sourceWalkFunc] err:", err) } return nil }}func parseFile(currfile string, done func()) { if done != nil { defer done() } //这地方要注意,配置要对。 destFile := strings.Replace(currfile, repConf.SourceDir, repConf.DestDir, -1) if destFile == currfile { panic("[parseFile] ERROR 没有替换对. SourceDir与DestDir配置出问题了。请检查Json配置.") } destDir := filepath.Dir(destFile) if _, er := os.Stat(destDir); os.IsNotExist(er) { if err := os.MkdirAll(destDir, 0700); err != nil { fmt.Println("[parseFile] MkdirAll ", destDir) panic(err) } } fmt.Println("[parseFile] 源文件:", currfile) fmt.Println("[parseFile] 目标文件:", destFile) ///////////////////////////////////////////////// oldFile, err := os.Open(currfile) if err != nil { fmt.Println("[parseFile] Failed to open the input file ", oldFile) return } defer oldFile.Close() newFile, err := os.Create(destFile) if err != nil { panic(err) } defer newFile.Close() f1 := func(ext string) bool { for _, e := range repConf.FileExtension { if ext == e { return true } } return false } if f1(filepath.Ext(currfile)) { copyRepFile(newFile, oldFile) extFileNum++ } else { if _, err := io.Copy(newFile, oldFile); err != nil { panic(err) } otherFileNum++ }}func copyRepFile(newFile, oldFile *os.File) { br := bufio.NewReader(oldFile) bw := bufio.NewWriter(newFile) for { row, err1 := br.ReadString(byte('/n')) if err1 != nil { break } str := string(row) if str == "" { continue } ret := repReplacer.Replace(str) //fmt.Println("[copyRepFile] str:", str) //fmt.Println("[copyRepFile] ret:", ret) if _, err := bw.WriteString(ret); err != nil { panic(err) } } bw.Flush()}func parseJsonFile() { f, err := os.Open(flagFile) if err != nil { panic("[parseJsonFile] open failed!") } defer f.Close() j, err := ioutil.ReadAll(f) if err != nil { panic("[parseJsonFile] ReadAll failed!") } err = json.Unmarshal(j, &repConf) if err != nil { fmt.Println("[parseJsonFile] json err:", err) panic("[parseJsonFile] Unmarshal failed!") } fmt.Println(" ------------------------------------------------------") fmt.Println(" 源目录:", repConf.SourceDir) fmt.Println(" 目标目录:", repConf.DestDir) fmt.Println(" 仅包含的指定扩展名的文件:", repConf.FileExtension) for _, e := range repConf.FileExtension { fmt.Println(" 文件扩展名:", e) } arr := make([]string, 0, 1) for _, v := range repConf.ReplaceWhere { fmt.Println(" 原文本:", v.FindWhat, " 替换为:", v.ReplaceWith) arr = append(arr, v.FindWhat) arr = append(arr, v.ReplaceWith) } repReplacer = strings.NewReplacer(arr...) fmt.Println(" ------------------------------------------------------") if repConf.SourceDir == "" || repConf.DestDir == "" { panic("[parseJsonFile] 目录设置不对!") }}

贴一个Windows下的例子:

Windows配置例子: {"sourcedir":"E://xclgo//src//test//aaa//","destdir":"E://xclgo//src//test//bbb//","fileext":[".go",".conf"],"replacewhere":[{ "findwhat":"parseFile", "replacewith":"----parseFile----" }, { "findwhat":"172.18.1.101", "replacewith":"192.168.1.101" }]}运行结果:E:/xclgo/src/test>go run batchreplace.go ------------------------------------------------------ 源目录: E:/xclgo/src/test/aaa/ 目标目录: E:/xclgo/src/test/bbb/ 仅包含的指定扩展名的文件: [.go .conf] 文件扩展名: .go 文件扩展名: .conf 原文本: parseFile 替换为: ----parseFile---- 原文本: 172.18.1.101 替换为: 192.168.1.101 ------------------------------------------------------dirname: E:/xclgo/src/test/aaa/[sourceWalkFunc] err: <nil>[parseFile] 源文件: E:/xclgo/src/test/aaa/testfile.go[parseFile] 目标文件: E:/xclgo/src/test/bbb/testfile.goelapsed 0.004000 seconds处理统计 处理指定类型文件: 1 处理其它文件: 0

就不演示包含子目录的了。  其中参数就是把Json内容存到“flag.json”文件里,运行时会自动去读取配置。

 

BLOG: http://blog.csdn.net/xcl168





分享给朋友:
您可能感兴趣的文章:
随机阅读: