
У меня есть 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 ,
внутренние двойные кавычки не считались разделителем, поскольку они ,
больше им не являются. Я также удалил двойные кавычки, "
поскольку они не нужны.
Я попытался автоматизировать это для каждой строки в моем CSV-файле с помощью sed следующим образом:
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 могут быть очень сложными. Вы можете получить экранированную кавычку где-то в строке, и регулярное выражение для ее обработки будет нечитаемым и подверженным ошибкам.
Я бы предложил такой инструмент, какcvskitили небольшой скрипт на 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
вероятно, знает, как с этим справиться, если использоватьправильные варианты, но кстати, это можно сделать и с помощью 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;