Golang文件清理功能支持
Golang文件清理功能支持 我有一个CSV文件看起来已损坏,因此我想进行一些清理。
我想先将其作为txt文件处理以进行清理,然后再作为CSV读取。
文件中有些字段包含"",有些则没有,并且注意到那些包含""的字段内部有,,例如:
有些数字显示为:"2,15.0,有些显示为22.3,不带""
有些文本显示为:Manager, Supply Chain,有些显示为Supervisor,不带""
我解决这个问题的方法是:
- 如果
,位于""之间,则从文件中移除它 - 从文件中移除
""
假设文件中的行如下:
John, supervisor, 20.22
Mark, "Manager, SC", "3,200.0"
Joseph, "Technician, Electrical", 15.2
"Selphia, Henry", "Manager, Lab", "4,250.0"
那么清理后的文件应该是:
John, supervisor, 20.22
Mark, Manager SC, 3200.0
Joseph, Technician Electrical, 15.2
Selphia Henry, Manager Lab, 4250.0
有什么想法或建议吗?
更多关于Golang文件清理功能支持的实战教程也可以访问 https://www.itying.com/category-94-b0.html
4 回复
非常感谢,我尝试了以下代码:
package main
import (
"bytes"
"encoding/csv"
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
)
// https://yourbasic.org/golang/regexp-cheat-sheet/
func main() {
// str1 := `"Selphia, Henry", "Manager, Lab", "4,250.0"` // {}
input, err := ioutil.ReadFile("sample.csv")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
re := regexp.MustCompile(`"\s*,\s*"|,\s*"|",\s*`)
str := re.ReplaceAllString(string(input), `\t`) // `0x09`
output := bytes.Replace([]byte(str), []byte(`"`), []byte(""), -1) // remove the `"` at begining and at end of each line
if err = ioutil.WriteFile("modified.tsv", output, 0666); err != nil {
fmt.Println(err)
os.Exit(1)
}
fr, err := os.Open("modified.tsv")
if err != nil {
log.Fatal("Unable to open output")
}
//methods.FailOnError(err)
defer fr.Close()
rdr := csv.NewReader(fr)
rdr.Comma = '\t'
rows, err := rdr.ReadAll()
if err != nil {
log.Fatal("Unable to read data: ")
}
fmt.Printf("%s", rows[1])
}
输出结果是:
[Mark\tManager, SC\t3,200.0]
如果我尝试这样读取:
fmt.Printf("%s", rows[1][2])
我得到:
panic: runtime error: index out of range [2] with length 1
在Go中处理这种CSV清理需求,可以使用标准库的encoding/csv配合自定义清理逻辑。以下是实现方案:
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
"strings"
)
func cleanCSV(inputPath, outputPath string) error {
// 读取原始文件
inputFile, err := os.Open(inputPath)
if err != nil {
return err
}
defer inputFile.Close()
// 创建输出文件
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
// 创建CSV读写器
reader := csv.NewReader(inputFile)
writer := csv.NewWriter(outputFile)
defer writer.Flush()
// 设置CSV读取选项
reader.LazyQuotes = true
reader.TrimLeadingSpace = true
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
return err
}
// 清理每个字段
cleanedRecord := make([]string, len(record))
for i, field := range record {
cleanedRecord[i] = cleanField(field)
}
// 写入清理后的记录
if err := writer.Write(cleanedRecord); err != nil {
return err
}
}
return nil
}
func cleanField(field string) string {
// 移除双引号
field = strings.ReplaceAll(field, "\"", "")
// 移除逗号(保留数字中的小数点)
var result strings.Builder
for _, r := range field {
if r != ',' || (r == ',' && strings.Contains(field, ".")) {
// 处理数字中的逗号:移除千位分隔符
if r == ',' && strings.Contains(field, ".") {
continue
}
result.WriteRune(r)
}
}
return strings.TrimSpace(result.String())
}
func main() {
// 示例使用
err := cleanCSV("input.csv", "cleaned.csv")
if err != nil {
fmt.Printf("清理失败: %v\n", err)
return
}
fmt.Println("文件清理完成")
}
如果需要更精确的数字处理,可以添加专门的数字清理函数:
func cleanNumericField(field string) string {
// 移除所有非数字字符(除了小数点和负号)
var result strings.Builder
decimalFound := false
for _, r := range field {
switch {
case r >= '0' && r <= '9':
result.WriteRune(r)
case r == '.' && !decimalFound:
result.WriteRune(r)
decimalFound = true
case r == '-':
result.WriteRune(r)
}
}
return result.String()
}
对于混合类型字段的清理,可以使用类型检测:
func cleanMixedField(field string) string {
// 移除双引号
field = strings.ReplaceAll(field, "\"", "")
// 检查是否为数字字段(包含逗号和小数点)
if strings.Contains(field, ".") && strings.Contains(field, ",") {
return cleanNumericField(field)
}
// 文本字段:移除所有逗号
return strings.ReplaceAll(field, ",", "")
}
这个实现会正确处理你的示例数据,生成符合要求的清理后CSV文件。


