批量替换和转移目录的东东
发布时间:2020-12-16 18:38:05 所属栏目:大数据 来源:网络整理
导读:拷,1点半了,写太晚了。 总之是个好东东。直接上代码了,不解释。 /*批量替换和转移目录的东东 遍历指定目录(包含子目录),对于指定扩展名的文件, 查找并替换文件内容中的指定字符串,并 将其输出到新的目录(包含子目录)下。原文件内容不变。 至于其它非指
拷,1点半了,写太晚了。 总之是个好东东。直接上代码了,不解释。 /* 批量替换和转移目录的东东 遍历指定目录(包含子目录),对于指定扩展名的文件, 查找并替换文件内容中的指定字符串,并 将其输出到新的目录(包含子目录)下。原文件内容不变。 至于其它非指定的文件,也一并复制一份到新目录下。 使用Josn作为配置文件. Author:XiongChuanLiang Date:2015-10-23 Linux 配置示例: { "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 main import ( "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 ReplaceConf var repReplacer *strings.Replacer var extFileNum,otherFileNum int var maxGoroutines int func 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 secondsn",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,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:xclgosrctestaaa","destdir":"E:xclgosrctestbbb","replacewhere":[{ "findwhat":"parseFile","replacewith":"----parseFile----" },"replacewith":"192.168.1.101" }] } 运行结果: E:xclgosrctest>go run batchreplace.go ------------------------------------------------------ 源目录: E:xclgosrctestaaa 目标目录: E:xclgosrctestbbb 仅包含的指定扩展名的文件: [.go .conf] 文件扩展名: .go 文件扩展名: .conf 原文本: parseFile 替换为: ----parseFile---- 原文本: 172.18.1.101 替换为: 192.168.1.101 ------------------------------------------------------ dirname: E:xclgosrctestaaa [sourceWalkFunc] err: <nil> [parseFile] 源文件: E:xclgosrctestaaatestfile.go [parseFile] 目标文件: E:xclgosrctestbbbtestfile.go elapsed 0.004000 seconds 处理统计 处理指定类型文件: 1 处理其它文件: 0 就不演示包含子目录的了。 其中参数就是把Json内容存到“flag.json”文件里,运行时会自动去读取配置。
BLOG: http://blog.csdn.net/xcl168 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |