
Ich habe eine CSV-Datei, die ich in eine MySQL-Tabelle laden muss. Ich verlasse mich darauf, dass die Spaltenenden durch das ,
Zeichen gekennzeichnet sind. Deshalb ist es wichtig, dass das ,
nicht anderswo als als Spaltentrennzeichen erscheint.
Ich habe einige Zeilen gefunden, die eine Spalte mit ,
doppelten Anführungszeichen enthalten, beispielsweise eine Zeile wie diese:
12,"name, brand - something, something",age,sex,,,,"name, brand - something, something, something",,,,,
Muss konvertiert werden in:
12,name; brand - something; something,age,sex,,,,name; brand - something; something; something,,,,,
Wie Sie sehen, habe ich die ,
Anführungszeichen darin durch ersetzt ;
, sodass die ,
Anführungszeichen darin beim Laden der Datei in MySQL nicht mehr als Trennzeichen betrachtet werden, da dies nicht ,
mehr der Fall ist. Ich habe auch die Anführungszeichen entfernt, "
da sie nicht benötigt werden.
Ich habe versucht, dies für jede Zeile in meiner CSV-Datei mit sed wie folgt zu automatisieren:
sed -e 's/"\*,\*"/"\*;\*"/g' -e 's/"//g' input.csv > output.csv
Das Ergebnis hat jedoch nicht die ,
in den doppelten Anführungszeichen enthaltenen ersetzt ;
. Es hat lediglich die doppelten Anführungszeichen entfernt:
12,name, brand - something, something,age,sex,,,,name, brand - something, something, something,,,,,
Antwort1
CSV-Dateien können sehr knifflig sein. Es kann sein, dass irgendwo in der Zeile ein maskiertes Anführungszeichen steht und der reguläre Ausdruck, der damit umgeht, unlesbar und fehleranfällig ist.
Ich würde entweder ein Tool wieAbonnierenoder ein kleines Skript in Perl oder Python. Dieses schnell erstellte Programm in Python sollte es tun:
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])
Antwort2
Wie bereits von @steeldriver erwähnt, mysql
weiß wahrscheinlich, wie man damit umgeht, wenn diedie richtigen Optionen, aber das können Sie, falls Sie das wissen, auch mit awk machen:
awk -v RS='"' -v ORS= 'NR % 2 || gsub(/,/,";") || 1'
12,name; brand - something; something,age,sex,,,,name; brand - something; something; something,,,,,
Oder unter Beibehaltung der Anführungszeichen:
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",,,,,
Dabei wird der gleiche Trick verwendet wieHier, nur zurückgesetzt: anstatt den Teil zu änderndraußendie Anführungszeichen, ich ändere den TeilinnenDie Zitate.
Antwort3
Die beste Antwort, die ich gefunden habe, ist die Verwendung von MySQL selbst durch Hinzufügen dieser Zeile:
OPTIONALLY ENCLOSED BY '"'
So sieht beispielsweise die Ladeabfrage aus:
LOAD DATA INFILE 'filename.csv' INTO TABLE table_name
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES;