加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间: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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读