整体思路如下:
此程序为Go语言编写,可以递归遍历某一个目录下的所有代码文件,并通过指定的正则表达式条件进行筛选,后输将筛选结果输出到某一文件中:
代码中:/Users/wang/GolandApp/process/manager/invent
应替换为遍历目录的绝对路径;
isMatch, matchErr := regexp.MatchString(
(in|IN)\s(, v)
该行为正则表达式对每一行的内容进行条件匹配,如果匹配则isMatch为true ,进行对该行的输出或者其他处理;
/Users/GolandApp/tasks/test/filter_ans
为遍历目标目录后寻找到的匹配内容输出到的目标文件
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"runtime/debug"
"strconv"
"strings"
)
// 方法入口
func main() {
// 递归遍历该path目录下的所有内容(/Users/wang/GolandApp/process/manager/invent 绝对路径),处理函数为walkFunc
filepath.Walk("/Users/wang/GolandApp/process/manager/invent", walkFunc)
}
// 处理函数实现
func walkFunc(path string, info os.FileInfo, err error) error {
// 判断文件类型--目录跳过
if info.IsDir() {
return nil
}
// 获取操作文件的句柄
file, openErr := os.Open(path)
if openErr != nil {
fmt.Println(openErr.Error())
}
// 设置读缓冲区,并读取文件内容
var readBuffer = make([]byte, 1024000)
_, readErr := file.Read(readBuffer)
if readErr != nil {
fmt.Println(readErr.Error())
}
// 读取内容转换为字符串
content := string(readBuffer)
// 字符串分割(按行分割)将读取到的文件内容按行进行分割,对应代码中的一行行代码
lines := strings.Split(content, "\n")
// 获取写目标文件(筛选结果 输出文件)句柄。O_APPEND 输出文件追加写方式
writeFile, err := os.OpenFile("/Users/GolandApp/tasks/test/filter_ans", os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
fmt.Println("文件打开失败", err)
}
// 写入文件时,使用带缓存的 *Writer
write := bufio.NewWriter(writeFile)
// 遍历文件中每一行的内容
var is_exist = false
for i, v := range lines { //遍历代码文件中的每一行代码进行正则匹配照出我们想要的内容
// 设定该行的正则匹配字符串 ,也就是我们进行筛选文件中内容的条件【该处的正则匹配条件是重点】如下匹配含 in/IN 的所有代码行
isMatch, matchErr := regexp.MatchString(`(in|IN)\s\(`, v)
if matchErr != nil {
fmt.Println(matchErr.Error())
return matchErr
}
// 如果匹配则将文件--行号--该行内容输出到目标文件中
if isMatch {
is_exist = true
user := getGitBlameInfo(path, i+1)
write.WriteString(path + "\tLine:" + strconv.FormatInt(int64(i+1), 10) + "\tContent:" + strings.TrimSpace(v) + "\tUser:" + user + "\n")
}
if is_exist && i == len(lines)-1 {
write.WriteString("\n")
}
}
if !info.IsDir() {
write.Flush()
}
file.Close()
return nil
}
// 获取该行git 提交信息情况
func getGitBlameInfo(targetPath string, line int) string {
command := "git blame -L " + util.ToString(line) + "," + util.ToString(line) + " " + targetPath
content := CmdResult(command)
strList := strings.Split(content, "(")
if len(strList) < 2 {
println(command)
println(targetPath)
println(content)
os.Exit(-1)
return ""
}
splitList := strings.Split(strList[1], " ")
if len(splitList) < 1 {
println(command)
println(targetPath)
println(content)
os.Exit(-2)
return ""
}
blameUser := splitList[0]
return blameUser
}
func CmdResult(command string) string {
defer func() {
if err := recover(); err != nil {
logger.LogError("CmdResult失败:", fmt.Sprint(err), "\n", string(debug.Stack()))
}
}()
var cmd *exec.Cmd
if runtime.GOOS == "windows" {
cmd = exec.Command("cmd", "/C", command)
} else {
cmd = exec.Command("/bin/sh", "-c", command)
}
defer func() {
cmd.Wait()
if cmd.Process != nil {
cmd.Process.Kill()
}
cmd.Wait()
}()
output, _ := cmd.Output()
return string(output)
}