Ersetzen von Kommas in doppelten Anführungszeichen in einer CSV-Datei mit sed

Ersetzen von Kommas in doppelten Anführungszeichen in einer CSV-Datei mit sed

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, mysqlweiß 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;

verwandte Informationen