Um einige Daten in ein bestimmtes Tool importieren zu können, muss ich eine CSV-Datei aus diesem Format transformieren
"data","data","data data","data","123"
in dieses Format
data;data;data data;data;123
Die Spalten enthalten nie "
, ;
oder ,
aber es können Räume. Derzeit verwende ich Folgendes
sed -e 's/","/;/g' -e 's/"//g' input.csv > output.csv
Obwohl dies gut funktioniert, frage ich mich, ob dies eleganter gemacht werden kann, dh
- Ist sed das richtige (Standard Unix) Tool für den Job?
- Wäre es möglich, beide Ausdrücke zu einem zusammenzuführen?
Danke für deinen Beitrag!
Was Sie bevorzugen (Perl, Sed, Awk), liegt bei Ihnen; Sie werden alle die Arbeit erledigen. Da Sie nach sed gefragt haben und die anderen veröffentlicht sind, können Sie loslegen. Dies ist eine einfachere Form Ihrer Regex und funktioniert mit Ihrer Beispielzeile:
Beachten Sie können die beiden Ausdrücke mit einem Semikolon nach jeder Substitution verbinden. Getestet mit GNU sed v4.1.5.
Hier sind Ihre ursprünglichen Ausdrücke verbunden:
Ich bin mir ziemlich sicher, dass es möglich ist, die beiden Substitutionen zusammenzuführen. Ich bin mir nicht sicher, was es ohne weiteres sein würde, und ich bin mir ziemlich sicher, dass das Ergebnis viel weniger lesbar sein wird als das Skript oben. Wenn mir etwas einfällt (oder jemand anderes in den Kommentaren wiegt), füge ich es hier hinzu.
quelle
Da Sie mit Aufzeichnungen zu tun haben,
awk
ist dies sinnvoller. Das heißt, es ist nicht wirklich gut in CSV, da die Feldbegrenzer etwas variabel sind. Wenn Sie jedoch sicher sind, dass alle Felder von doppelten Anführungszeichen umgeben sind, funktioniert dies:Dies setzt das Eingabefeldtrennzeichen von awk auf "
","
" (einschließlich des inneren Satzes von Doppelzitaten). Dies funktioniert fast, außer dass Sie sich mit den führenden und nachfolgenden Doppelzitaten befassen müssen, die mit dergsub
Funktion entfernt werden. Das$1=$1
zwingt ihn, den Datensatz mit dem neuen Ausgabefeldtrennzeichen neu zu kompilieren, das wie;
im BEGIN-Block definiert wurde. Dannprint
druckt den gesamten Datensatz aus.Das ist etwas aufgeräumter:
Es setzt das Eingabefeldtrennzeichen auf einen regulären Ausdruck, der die doppelten Anführungszeichen am Anfang und Ende des Datensatzes enthält, bewirkt aber auch, dass ein leeres Anfangs- und Nachlauffeld ausgedruckt wird. Sie können das nachfolgende Feld leicht entfernen:
NF
ist die Anzahl der Felder, und die Reduzierung um eins springt vom letzten Feld ab. Aber ich kann mir keinen Weg vorstellen, das erste Feld abzuhacken.Wenn Sie jedoch wissen, dass die Eingabe immer fünf Felder enthält, können Sie dies tun:
Beachten Sie, dass dadurch das
$1=$1
Konstrukt entfernt wird, das wir nur benötigen, wenn wir die (implizierten) $ 0 drucken.Alles in allem würde ich wahrscheinlich Perl und eines der vielen verfügbaren CSV-Module auf CPAN verwenden .
quelle