如果使用 sed 在 CSV 文件中的双引号内找到逗号,则替换逗号

如果使用 sed 在 CSV 文件中的双引号内找到逗号,则替换逗号

我有一个 CSV 文件,需要将其加载到 MySQL 表中。我依靠识别以,字符结尾的列。这就是为什么,除了作为列分隔符之外,不要出现在其他地方,这一点很重要。

,我发现一些行包含带有内部双引号的列。例如这样的一行:

12,"name, brand - something, something",age,sex,,,,"name, brand - something, something, something",,,,,

需要转换为:

12,name; brand - something; something,age,sex,,,,name; brand - something; something; something,,,,,

如您所见,我将,内部双引号替换为,;以便当我在 MySQL 中加载文件时,,内部双引号不再被视为分隔符,。我还删除了双引号,"因为不需要它们。

我尝试使用 sed 对 CSV 文件中的每一行自动执行此操作,如下所示:

sed -e 's/"\*,\*"/"\*;\*"/g' -e 's/"//g' input.csv > output.csv

但结果并没有,将双引号内的 替换为;。它只删除了双引号:

12,name, brand - something, something,age,sex,,,,name, brand - something, something, something,,,,,

答案1

csv 文件可能非常棘手。您最终可能会在行中的某个位置出现转义引号,而要处理的正则表达式将不可读且容易出错。

我建议使用类似的工具简历工具包或者 Perl 或 Python 中的小脚本。这个用 python 快速编写的程序应该可以做到这一点:

import csv

with open('input.csv',mode='r') as csv_file:
   csv_reader = csv.reader(csv_file)
   for row in csv_reader:
       print (',').join([f.replace(',',';') for f in row])

答案2

正如@steeldriver 已经提到的,mysql可能知道如果使用正确的选择,但是FWIW你可以用awk做到这一点:

awk -v RS='"' -v ORS= 'NR % 2 || gsub(/,/,";") || 1'

12,name; brand - something; something,age,sex,,,,name; brand - something; something; something,,,,,

或者,同时保留随附的引号:

awk -v RS='"' -v ORS= '{if(NR % 2) print; else{gsub(/,/,";");print RS $0 RS}}'

12,"name; brand - something; something",age,sex,,,,"name; brand - something; something; something",,,,,

这使用了与以下相同的技巧这里,仅恢复:而不是修改部分外部引号,我正在修改部分里面引号。

答案3

我发现的最佳答案是通过添加以下行来使用 MySQL 本身:

OPTIONALLY ENCLOSED BY '"'

例如,加载查询如下所示:

LOAD DATA INFILE 'filename.csv' INTO TABLE table_name 
  FIELDS TERMINATED BY ',' 
  OPTIONALLY ENCLOSED BY '"'
  IGNORE 1 LINES;

相关内容