文本内容提取 求助

log.txt (9.5 KB)
我现在有一个一堆文本文件大概每个文件2G 左右, 我现在需要提取文件中得每行sql 语句,但是他们会换行, 用scanner := bufio.NewScanner(file) buf := make([]byte, maxCapacity) scanner.Buffer(buf, maxCapacity) scanner.Split(scanSQL) 这种方式去获取会导致内存占用过高被系统杀死
有没有大佬 帮助一下 Golang 实现

const maxCapacity = 2048 * 1024 * 1024
func mustSql(filePath string, dbOp *gorm.DB) {
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	tasks := make(chan string, workerCount)
	for i := 0; i < workerCount; i++ {
		wg.Add(1)
		go worker(i, tasks, &wg, dbOp)
	}
	scanner := bufio.NewScanner(file)
	buf := make([]byte, maxCapacity)
	scanner.Buffer(buf, maxCapacity)
	scanner.Split(scanSQL)
	count := 0
	r := regexp.MustCompile(`(?s)(insert into sip_info\(.+?\) values\(.+?\))`)
	for scanner.Scan() {
		line := scanner.Text()
		matches := r.FindStringSubmatch(line)
		if len(matches) > 1 {
			insertSql := matches[1]
			tasks <- insertSql
			count++
		}
	}
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
	util.LOG.Infof("Total number of SQL statements: %d  path:%s", count, filePath)
	util.LOG.Info("Concurrent SQL execution completed!")

	close(tasks)
	wg.Wait()
}


func scanSQL(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := strings.Index(string(data), "siprecorder.c"); i >= 0 {
		return i + 1, data[0:i], nil
	}
	if atEOF {
		return len(data), data, nil
	}
	return
}

上面是现有得代码

1 个赞

gpt也没办法吗

没弄出来, 最后用了死办法解决,每次都去比对一边

for {
		// 逐行读取文件
		line, err := reader.ReadString('\n')
		if err != nil {
			if err.Error() == "EOF" {
				break
			}
			fmt.Println("Error reading file:", err)
			return
		}
		// 匹配SQL语句
		sqlBuilder.WriteString(line)
		sql := sqlBuilder.String()
		if regexpText.MatchString(sqlBuilder.String()) {
			tasks <- sql
			sqlBuilder.Reset()
			count++
		}
	}
1 个赞

你应该先把sql的换行去掉,比如:每行开始如果不是时间,就把这行放到上一行后面,这个预处理之后再去解析sql

记录行首有固定格式,先逐行读取,并变量储存去掉行首字符,
读取到下个记录行首,就对日志内容进行sql判断,如果是要的,就写入其它文件或是数据库,
建议用函数处理,而不是for,容易文件大,占用高变成不响应,中间还可以加入中断监听,保存进度,后续用seek继续,

1 个赞