批量替换和转移目录的东东
发布时间: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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
