Wenn ich mit CSV arbeite, führen unerwünschte Kommas („,“) zu einer Irreführung meiner CSV-Datei, was zu Inkonsistenzen führt.
Einzelheiten finden Sie weiter unten.
Meine Beispiel-CSV-Datei:
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
Ich möchte das Endergebnis wie folgt:
1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4
Nachdem ich die Anführungszeichen hinzugefügt habe, werde ich „|“ durch „“, ersetzen, damit meine CSV wie erwartet funktioniert.
Ich habe den folgenden Befehl verwendet, aber das Ergebnis ist nicht das erwartete.
sed -e 's/,/"&"/' file1.txt
Antwort1
Verwendung csvformat
voncsvkit
, und unter der Annahme, dass das Endergebnis eine CSV-Datei mit Komma als Trennzeichen sein soll (wie im Text der Frage beschrieben):
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
Dadurch wird die CSV-Datei neu formatiert. |
Statt -Zeichen als Trennzeichen zu verwenden, wird das Standardkomma als Trennzeichen verwendet. Dabei werden die Felder, die in Anführungszeichen gesetzt werden müssen, richtig in Anführungszeichen gesetzt.
Dadurch werden auch Felder mit eingebetteten Zeilenumbrüchen ordnungsgemäß behandelt:
$ cat file
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
2|"line 1,
line2"|5
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
2,"line 1,
line2",5
Wenn Sie ein Dokument in einem strukturierten Dokumentformat wie CSV, JSON, XML, YAML, TOML usw. haben, gibt es keinen Grundnichtum einen Parser für dieses Dokumentformat zu verwenden, um dieses Dokument zu analysieren.
Antwort2
Du könntest es tun:
awk -F'[|]' -v OFS=',' -v q='"' '{ for(i=1; i<=NF; i++) $i=q $i q }1' infile
mit -F'[|]'
haben wir den Eingabefeldtrenner definiert.
mit -v OFS=','
haben wir den Ausgabefeldtrenner definiert.
NF
identifiziert, wie viele Felder in jeder Zeile/jedem Datensatz vorhanden sind, basierend auf dem FS (Eingabefeldtrenner), also durchlaufen wir die Anzahl der Felder und fügen für jedes von ihnen doppelte Anführungszeichen hinzu und drucken das endgültige Update in der Zeile mitawks 1
Redewendungfür den Druck.
beachten Sie, dass mit diesem Befehl alle Felder in Anführungszeichen gesetzt werden, was für eine gültige CSV-Datei jedoch offensichtlich kein Problem darstellt.
Antwort3
Mit sed
:
$ sed 's/[^|]*,[^|]*/"&"/g; y/|/,/' ip.txt
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
s/[^|]*,[^|]*/"&"/g
Fügen Sie allen Feldern doppelte Anführungszeichen hinzu, die Folgendes enthalten:,
y/|/,/
ändere alle|
Zeichen in,
Mit perl
:
perl -F'\|' -lane 'print join ",", map {/,/ ? qq("$_") : $_} @F'
Dies wird |
als Eingabefeldtrennzeichen verwendet. Anschließend map
werden für alle Felder, die enthalten, doppelte Anführungszeichen hinzugefügt ,
. Schließlich join
wird verwendet, um die Felder mit ,
Zeichen zu verbinden.
Antwort4
Ein anderer sed
Weg:
sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data
Oder wenn Sie sed
das Laden von unterstützen ERE
, z. B. GNU sed
, können Sie die gesamte Escape-Arbeit vermeiden:
sed -E 's;([^|]+)\|([^|]+)\|(.+)$;\1,"\2",\3;' data
Man kann die Tatsache, dass nur die mittlere Gruppe |
an jeder Grenze durch ein abgegrenzt ist, ausnutzen und sie sed
noch weiter verkürzen:
sed 's;|\([^|]*\)|;,"\1",;' data
Natürlich -E
können Sie auch hier, wenn Ihr SED-Support vorhanden ist, die Datei laden ERE
und sich so einen mühsamen Escape-Job ersparen.