Suchen und fügen Sie Anführungszeichen zwischen bestimmten Zeichenfolgen ein

Suchen und fügen Sie Anführungszeichen zwischen bestimmten Zeichenfolgen ein

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 csvformatvoncsvkit, 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.
NFidentifiziert, 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 1Redewendungfü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/[^|]*,[^|]*/"&"/gFü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 mapwerden für alle Felder, die enthalten, doppelte Anführungszeichen hinzugefügt ,. Schließlich joinwird verwendet, um die Felder mit ,Zeichen zu verbinden.

Antwort4

Ein anderer sedWeg:

  sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data

Oder wenn Sie seddas 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 sednoch weiter verkürzen:

sed 's;|\([^|]*\)|;,"\1",;' data

Natürlich -Ekönnen Sie auch hier, wenn Ihr SED-Support vorhanden ist, die Datei laden EREund sich so einen mühsamen Escape-Job ersparen.

verwandte Informationen