![如果使用 sed 在 CSV 文件中的双引号内找到逗号,则替换逗号](https://linux22.com/image/170138/%E5%A6%82%E6%9E%9C%E4%BD%BF%E7%94%A8%20sed%20%E5%9C%A8%20CSV%20%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E5%8F%8C%E5%BC%95%E5%8F%B7%E5%86%85%E6%89%BE%E5%88%B0%E9%80%97%E5%8F%B7%EF%BC%8C%E5%88%99%E6%9B%BF%E6%8D%A2%E9%80%97%E5%8F%B7.png)
我有一个 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;