2021-11-17 09:59:06 +00:00
|
|
|
package script
|
|
|
|
|
|
|
|
|
|
import (
|
2023-12-05 16:29:38 +00:00
|
|
|
"bufio"
|
2024-10-24 15:26:07 +00:00
|
|
|
"fmt"
|
2021-11-17 09:59:06 +00:00
|
|
|
"io/ioutil"
|
|
|
|
|
"os"
|
2022-07-23 04:19:35 +00:00
|
|
|
"path/filepath"
|
2025-01-12 02:10:55 +00:00
|
|
|
"regexp"
|
2023-12-05 16:29:38 +00:00
|
|
|
"strings"
|
2021-11-17 09:59:06 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func FileIfExist(filePath string) bool {
|
|
|
|
|
_, err := os.Stat(filePath)
|
|
|
|
|
if nil != err {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-18 08:27:28 +00:00
|
|
|
func ReadFile(filePath string) ([]byte, error) {
|
2021-11-17 09:59:06 +00:00
|
|
|
content, err := ioutil.ReadFile(filePath)
|
|
|
|
|
if nil != err {
|
2021-11-21 14:37:13 +00:00
|
|
|
LogSystemError("Failed to read file (" + filePath + ")")
|
2021-11-18 08:27:28 +00:00
|
|
|
return content, err
|
2021-11-17 09:59:06 +00:00
|
|
|
}
|
2021-11-21 14:37:13 +00:00
|
|
|
LogSystemInfo("Success read file (" + filePath + ")")
|
2021-11-18 08:27:28 +00:00
|
|
|
return content, nil
|
2021-11-17 09:59:06 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-18 08:27:28 +00:00
|
|
|
func WriteFile(filePath string, content string) error {
|
2021-11-29 14:21:25 +00:00
|
|
|
err := ioutil.WriteFile(filePath, []byte(content), 0777)
|
|
|
|
|
if err != nil {
|
|
|
|
|
LogSystemError("Failed to write file (" + filePath + ")")
|
|
|
|
|
return err
|
2021-11-18 08:27:28 +00:00
|
|
|
}
|
2021-11-21 14:37:13 +00:00
|
|
|
LogSystemInfo("Success write file (" + filePath + ")")
|
2021-11-18 08:27:28 +00:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-28 12:19:40 +00:00
|
|
|
func AppendFileInNewLine(filePath string, content string) error {
|
2022-10-22 15:34:28 +00:00
|
|
|
err := CreateFileIfNotExist(filePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2021-11-28 12:19:40 +00:00
|
|
|
content = "\r\n" + content
|
2021-12-07 14:37:03 +00:00
|
|
|
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
|
2022-07-23 04:19:35 +00:00
|
|
|
if err != nil {
|
|
|
|
|
LogSystemError("Failed to open file (" + filePath + ")")
|
|
|
|
|
return err
|
|
|
|
|
} else {
|
2021-11-28 12:19:40 +00:00
|
|
|
_, err = file.WriteString(content)
|
|
|
|
|
if err != nil {
|
|
|
|
|
LogSystemError("Failed to append file (" + filePath + ")")
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
LogSystemInfo("Success append file (" + filePath + ")")
|
2022-07-23 04:19:35 +00:00
|
|
|
return err
|
2021-11-28 12:19:40 +00:00
|
|
|
}
|
|
|
|
|
|
2023-12-05 16:29:38 +00:00
|
|
|
func DeleteLinesWithText(filePath string, textToDelete string) error {
|
|
|
|
|
// 打开文件以供读写
|
|
|
|
|
file, err := os.OpenFile(filePath, os.O_RDWR, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
// 创建一个缓冲读取器
|
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
|
|
|
|
|
|
|
// 创建一个字符串切片,用于保存文件的每一行
|
|
|
|
|
var lines []string
|
|
|
|
|
|
|
|
|
|
// 逐行读取文件内容
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
|
line := scanner.Text()
|
|
|
|
|
|
|
|
|
|
// 检查行是否包含要删除的文本
|
|
|
|
|
if !strings.Contains(line, textToDelete) {
|
|
|
|
|
lines = append(lines, line)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 关闭文件
|
|
|
|
|
file.Close()
|
|
|
|
|
|
|
|
|
|
// 重新打开文件以供写入
|
|
|
|
|
file, err = os.OpenFile(filePath, os.O_RDWR|os.O_TRUNC, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
// 创建一个写入器
|
|
|
|
|
writer := bufio.NewWriter(file)
|
|
|
|
|
|
|
|
|
|
// 将修改后的内容写回文件
|
|
|
|
|
for _, line := range lines {
|
|
|
|
|
_, err := writer.WriteString(line + "\n")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 刷新缓冲区,确保所有数据被写入文件
|
|
|
|
|
err = writer.Flush()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-18 08:27:28 +00:00
|
|
|
func CreateFile(filePath string) error {
|
2022-07-23 04:19:35 +00:00
|
|
|
if _, e := os.Stat(filePath); os.IsNotExist(e) {
|
|
|
|
|
_ = os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
|
|
|
|
|
f, err := os.Create(filePath)
|
|
|
|
|
if nil != err {
|
|
|
|
|
LogSystemError(filePath + " create failed")
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer f.Close()
|
|
|
|
|
LogSystemInfo("Success create file " + filePath)
|
|
|
|
|
} else {
|
|
|
|
|
LogSystemInfo("File is exist " + filePath)
|
2021-11-17 09:59:06 +00:00
|
|
|
}
|
2021-11-18 08:27:28 +00:00
|
|
|
return nil
|
2021-11-17 09:59:06 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-22 15:34:28 +00:00
|
|
|
func CreateFileIfNotExist(filePath string) error {
|
|
|
|
|
if _, e := os.Stat(filePath); os.IsNotExist(e) {
|
|
|
|
|
_ = os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
|
|
|
|
|
f, err := os.Create(filePath)
|
|
|
|
|
if nil != err {
|
|
|
|
|
LogSystemError(filePath + " create failed")
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer f.Close()
|
|
|
|
|
LogSystemInfo("Success create file " + filePath)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-23 15:33:14 +00:00
|
|
|
func CopyFile(sourceFilePath string, targetFilePath string) error {
|
|
|
|
|
if !FileIfExist(sourceFilePath) {
|
|
|
|
|
panic("File is not found, " + sourceFilePath)
|
|
|
|
|
}
|
|
|
|
|
if !FileIfExist(targetFilePath) {
|
|
|
|
|
err := CreateFile(targetFilePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bytes, err := ReadFile(sourceFilePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
err = WriteFile(targetFilePath, string(bytes))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-27 10:41:34 +00:00
|
|
|
func CopyDir(sourceDir string, targetDir string) error {
|
|
|
|
|
dirs, err := os.ReadDir(sourceDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
err = MkDir(targetDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
for _, dir := range dirs {
|
|
|
|
|
newSourceDir := filepath.Join(sourceDir, dir.Name())
|
|
|
|
|
newTargetDir := filepath.Join(targetDir, dir.Name())
|
|
|
|
|
if dir.IsDir() {
|
|
|
|
|
err := CopyFile(newSourceDir, newTargetDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
LogSystemError("Failed to copy dir from [" + newSourceDir + "] to [" + newTargetDir + "]")
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
err := CreateFileIfNotExist(newTargetDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
err = CopyFile(newSourceDir, newTargetDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-18 08:27:28 +00:00
|
|
|
func MkDir(dirPath string) error {
|
2021-11-17 09:59:06 +00:00
|
|
|
err := os.MkdirAll(dirPath, os.ModePerm)
|
|
|
|
|
if nil != err {
|
2021-11-21 14:37:13 +00:00
|
|
|
LogSystemError("Failed mkdir " + dirPath)
|
2021-11-18 08:27:28 +00:00
|
|
|
return err
|
2021-11-17 09:59:06 +00:00
|
|
|
}
|
2021-11-21 14:37:13 +00:00
|
|
|
LogSystemInfo("Success mkdir " + dirPath)
|
2021-11-18 08:27:28 +00:00
|
|
|
return nil
|
2021-11-17 09:59:06 +00:00
|
|
|
}
|
2024-10-24 15:26:07 +00:00
|
|
|
|
|
|
|
|
// FindConsecutiveMultilineTextInFile 查找文件中连续多行文本片段的开始和结束行号
|
|
|
|
|
func FindConsecutiveMultilineTextInFile(filePath string, multilineLines []string) (startLine, endLine int, err error) {
|
|
|
|
|
for i := range multilineLines {
|
2024-10-29 07:45:13 +00:00
|
|
|
multilineLines[i] = CleanString(multilineLines[i])
|
2024-10-24 15:26:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file, err := os.Open(filePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return -1, -1, err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
|
|
startLine = -1
|
|
|
|
|
endLine = -1
|
|
|
|
|
lineNumber := 0
|
|
|
|
|
matchIndex := 0
|
|
|
|
|
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
|
lineNumber++
|
|
|
|
|
// 清理文件中的当前行
|
2024-10-29 07:45:13 +00:00
|
|
|
lineText := CleanString(scanner.Text())
|
2024-10-24 15:26:07 +00:00
|
|
|
|
|
|
|
|
// 检查当前行是否匹配多行文本片段的当前行
|
|
|
|
|
if lineText == multilineLines[matchIndex] {
|
|
|
|
|
if startLine == -1 {
|
|
|
|
|
startLine = lineNumber // 记录起始行号
|
|
|
|
|
}
|
|
|
|
|
matchIndex++
|
|
|
|
|
// 如果所有行都匹配完成,记录结束行号并退出循环
|
|
|
|
|
if matchIndex == len(multilineLines) {
|
|
|
|
|
endLine = lineNumber
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 如果匹配失败,重置匹配索引和起始行号
|
|
|
|
|
matchIndex = 0
|
|
|
|
|
startLine = -1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
|
|
|
return -1, -1, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果未找到完整的多行文本片段,则返回 -1
|
|
|
|
|
if startLine == -1 || endLine == -1 {
|
|
|
|
|
return -1, -1, fmt.Errorf("未找到连续的多行文本片段")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LogSystemInfo("Success find content in file " + filePath + " line range: " + string(rune(startLine)) + "," + string(rune(endLine)))
|
|
|
|
|
return startLine, endLine, nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-29 07:45:13 +00:00
|
|
|
// CleanString 去除字符串中的首尾空白和中间的所有空格字符
|
|
|
|
|
func CleanString(str string) string {
|
|
|
|
|
if IsComment(str) {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
2025-01-12 02:10:55 +00:00
|
|
|
result := getAccountWithNumber(str)
|
2024-10-29 07:45:13 +00:00
|
|
|
// 去除 " ", ";", "\r"
|
2025-01-12 02:10:55 +00:00
|
|
|
result = strings.ReplaceAll(result, ",", "")
|
2024-12-22 15:14:53 +00:00
|
|
|
result = strings.ReplaceAll(result, " ", "")
|
2025-01-12 02:10:55 +00:00
|
|
|
// 过滤空白的商户信息 ““
|
|
|
|
|
result = strings.ReplaceAll(result, "\"\"", "")
|
2024-10-29 07:45:13 +00:00
|
|
|
result = strings.ReplaceAll(result, ";", "")
|
|
|
|
|
result = strings.ReplaceAll(result, "\r", "")
|
2025-01-12 02:10:55 +00:00
|
|
|
// 清楚汇率转换
|
|
|
|
|
|
2024-10-29 07:45:13 +00:00
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-12 02:10:55 +00:00
|
|
|
// 正则提取:
|
|
|
|
|
// Assets:Flow:Cash:现金 -20.00 USD {xxx CNY, 2025-01-01} -> Assets:Flow:Cash:现金 -20.00 USD
|
|
|
|
|
func getAccountWithNumber(str string) string {
|
|
|
|
|
// 定义正则表达式模式
|
|
|
|
|
pattern := `^[^\{]+`
|
|
|
|
|
// 编译正则表达式
|
|
|
|
|
re := regexp.MustCompile(pattern)
|
|
|
|
|
// 使用正则提取匹配的部分
|
|
|
|
|
return re.FindString(str)
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-29 07:45:13 +00:00
|
|
|
func IsComment(line string) bool {
|
|
|
|
|
trimmed := strings.TrimLeft(line, " ")
|
|
|
|
|
if strings.HasPrefix(trimmed, ";") {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
2024-10-24 15:26:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除指定行范围的内容
|
|
|
|
|
func RemoveLines(filePath string, startLineNo, endLineNo int) ([]string, error) {
|
|
|
|
|
file, err := os.Open(filePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
// 读取文件的每一行
|
|
|
|
|
var lines []string
|
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
|
lines = append(lines, scanner.Text())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查行号的有效性
|
|
|
|
|
if startLineNo < 1 || endLineNo > len(lines) || startLineNo > endLineNo {
|
|
|
|
|
return nil, fmt.Errorf("行号范围无效")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除从 startLineNo 到 endLineNo 的行(下标从 0 开始)
|
|
|
|
|
modifiedLines := append(lines[:startLineNo-1], lines[endLineNo:]...)
|
|
|
|
|
return modifiedLines, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在指定行号插入多行文本
|
|
|
|
|
func InsertLines(lines []string, startLineNo int, newLines []string) ([]string, error) {
|
|
|
|
|
// 检查插入位置的有效性
|
|
|
|
|
if startLineNo < 1 || startLineNo > len(lines)+1 {
|
|
|
|
|
return nil, fmt.Errorf("插入行号无效")
|
|
|
|
|
}
|
|
|
|
|
// 在指定位置插入新的内容
|
|
|
|
|
modifiedLines := append(lines[:startLineNo-1], append(newLines, lines[startLineNo-1:]...)...)
|
|
|
|
|
return modifiedLines, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 写回文件
|
|
|
|
|
func WriteToFile(filePath string, lines []string) error {
|
|
|
|
|
file, err := os.Create(filePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
// 将修改后的内容写回文件
|
|
|
|
|
writer := bufio.NewWriter(file)
|
|
|
|
|
for _, line := range lines {
|
|
|
|
|
_, err := writer.WriteString(line + "\n")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
LogSystemInfo("Success write content in file " + filePath)
|
|
|
|
|
return writer.Flush()
|
|
|
|
|
}
|