【Golang】读取yaml配置文件的批量替换文本小工具

比较传统的应用迁移(我司大量部署在tomcat上的程序),因为需要大面积修改或替换配置文件,手工一个个改不仅费时费力还难免出错,所以用go写了个小工具,打包成linux环境的可执行文件,用ansible分发执行即可。

测试执行效果

在这里插入图片描述
在这里插入图片描述

代码及配置

配置文件:text_replace.yaml

# 修改前的文件备份目录
backup_info:
  backup_path: ./bak/  

# 需要替换的文件,生产环境下写绝对路径比较好
file_infos:
  - file: ./initTopics.sh
  - file: ./test1.txt
  - file: ./test2.txt
  - file: ./test3.txt

# 需要替换的内容
replace_text_infos:
  - {old_text: 123, new_text: 一二三}
  - {old_text: 10.244.224.70, new_text: 10.22.161.209}

golang代码:text_replace.go

package main

import (
	"crypto/sha256"
	"fmt"
	log "github.com/sirupsen/logrus"
	"gopkg.in/yaml.v3"
	"io"
	"io/fs"
	"os"
	"strings"
	"unsafe"
)

// ReplaceInfo 配置文件结构体
type ReplaceInfo struct {
	BackupInfo       BackupInfo       `yaml:"backup_info"`
	FileInfos        FileInfos        `yaml:"file_infos"`
	ReplaceTextInfos ReplaceTextInfos `yaml:"replace_text_infos"`
}

type BackupInfo struct {
	BackupPath string `yaml:"backup_path"`
}

type FileInfos []struct {
	File string `yaml:"file"`
}

type ReplaceTextInfos []struct {
	OldText string `yaml:"old_text"`
	NewText string `yaml:"new_text"`
}

func main() {

	// 读取配置文件
	replaceInfo := ReadYaml("./text_replace.yaml")

	backupInfo, fileInfos, replaceTextInfos := replaceInfo.BackupInfo, replaceInfo.FileInfos, replaceInfo.ReplaceTextInfos

	// 创建备份目录
	err := os.MkdirAll(backupInfo.BackupPath, fs.ModePerm)
	if err != nil {
		log.Infof(err.Error())
	}

	// 遍历配置中每一个需要替换的文件
	for _, fileInfo := range fileInfos {
		// 读取要修改的文本文件
		content, isExist := ReadText(fileInfo.File)
		originalText, modifiedText := contesnt, content
		if isExist == false {
			log.Infof("文件不存在或为非文本文件,跳过  %v ", fileInfo.File)
			continue
		}

		// 替换文本
		for _, replaceTextInfo := range replaceTextInfos {
			modifiedText = strings.ReplaceAll(modifiedText, replaceTextInfo.OldText, replaceTextInfo.NewText)
		}

		// 对比文本修改前后是否一致,一致则跳过本次循环
		if originalText==modifiedText {
			log.Infof("文件中没有需要修改的文本 %v ", fileInfo.File)
			continue
		}

		// 备份
		fileBakup := fmt.Sprintf("%s%s", backupInfo.BackupPath, fileInfo.File)
		err := WriteText(fileBakup, originalText)
		if err != nil {
			log.Errorf(err.Error())
		}
		
		// 替换好的覆盖原文件
		WriteText(fileInfo.File, modifiedText)
		log.Infof("文件已替换完成 %v ,原文件备份至 %s ", fileInfo.File, fileBakup)
	}
}

// ReadYaml 读取配置文件
func ReadYaml(yamlInfo string) ReplaceInfo {
	dataBytes, err := os.ReadFile(yamlInfo)
	if err != nil {
		log.Fatalln("读取文件失败:", err)
	}

	config := ReplaceInfo{}
	err = yaml.Unmarshal(dataBytes, &config)
	if err != nil {
		log.Fatalln("解析 yaml 文件失败:", err)
	}
	return config
}

// ReadText 读取要修改的文本文件
func ReadText(path string) (text string, isExist bool) {
	file, err := os.Open(path)
	if err != nil {
		log.Infoln(err)
		isExist = false
		return
	}
	defer file.Close()

	data, err := io.ReadAll(file)
	if err != nil {
		log.Infoln(err)
		isExist = false
		return
	}
	return *(*string)(unsafe.Pointer(&data)), true
}

// WriteText 写入文本文件
func WriteText(src, content string) error {
	data := []byte(content)
	return os.WriteFile(src, data, os.ModePerm)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值