
Eu tenho um arquivo CSV que preciso carregar em uma tabela MySQL. Conto em identificar as colunas finalizadas pelo ,
caractere. É por isso que é importante que o ,
não apareça em outro lugar que não seja um separador de colunas.
Encontrei algumas linhas que contêm uma coluna ,
entre aspas duplas. por exemplo, uma linha como esta:
12,"name, brand - something, something",age,sex,,,,"name, brand - something, something, something",,,,,
Precisa ser convertido para:
12,name; brand - something; something,age,sex,,,,name; brand - something; something; something,,,,,
Como você pode ver, substituí as ,
aspas duplas internas por ;
para que quando eu carregar o arquivo no MySQL as ,
aspas duplas internas não sejam consideradas um separador, pois não são ,
mais. Também removi as aspas duplas "
porque não são necessárias.
Tentei automatizar isso para cada linha do meu arquivo CSV usando sed da seguinte maneira:
sed -e 's/"\*,\*"/"\*;\*"/g' -e 's/"//g' input.csv > output.csv
Mas o resultado não substituiu o ,
que vem entre aspas duplas por ;
. Apenas removeu as aspas duplas:
12,name, brand - something, something,age,sex,,,,name, brand - something, something, something,,,,,
Responder1
csv podem ser muito complicados. Você pode acabar tendo uma aspa de escape em algum lugar da linha e a expressão regular para lidar com isso seria ilegível e propensa a erros.
Eu sugeriria uma ferramenta comocvskitou um pequeno script em perl ou python. Este programa criado rapidamente em python deve servir:
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])
Responder2
Como já mencionado por @steeldriver, mysql
provavelmente sabe como lidar com isso se usar oopções certas, mas FWIW você pode fazer isso com o awk:
awk -v RS='"' -v ORS= 'NR % 2 || gsub(/,/,";") || 1'
12,name; brand - something; something,age,sex,,,,name; brand - something; something; something,,,,,
Ou, mantendo as aspas anexas:
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",,,,,
Isso está usando o mesmo truque queaqui, apenas revertido: em vez de modificar a peçaforaas aspas, estou modificando a partedentroas citações.
Responder3
A melhor resposta que encontrei é usar o próprio MySQL adicionando esta linha:
OPTIONALLY ENCLOSED BY '"'
Por exemplo, a consulta de carregamento é assim:
LOAD DATA INFILE 'filename.csv' INTO TABLE table_name
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES;