Ersetzen Sie die durch Kommas getrennte Datei durch ein Pipe-Zeichen, entfernen Sie jedoch keine Kommas oder Anführungszeichen usw. aus dem Textqualifiziererfeld. Entfernen Sie jedoch den Textqualifizierer!

Ersetzen Sie die durch Kommas getrennte Datei durch ein Pipe-Zeichen, entfernen Sie jedoch keine Kommas oder Anführungszeichen usw. aus dem Textqualifiziererfeld. Entfernen Sie jedoch den Textqualifizierer!

Meine Datei ist eine durch Kommas getrennte Datei und der Textqualifizierer ist ~, aber meine Anforderung besteht darin, die durch Kommas getrennte Datei durch eine durch |(Pipe) getrennte Datei zu ersetzen und den Textqualifizierer ~ durch nichts zu entfernen. Ich sollte jedoch keine Anführungszeichen oder doppelten Anführungszeichen oder andere Sonderzeichen innerhalb der im Textqualifizierer vorhandenen Daten entfernen. Beispiel: ~abc",~ ich brauche es als abc",

Unten sehen Sie den Inhalt meiner Quelldatei und die Art und Weise, wie ich die Ausgabe- oder bearbeitete Datei erwarte.

Quelldatei:

364034,2015652205,26722,2015,4,~C25753-4~,~TC25753,~,~2WD Double Cab 144.2" SLT,~,~Y~,40506.16,43555.00,1095.00,~043,005,006,007,003,008,016,041,012,029,068,027,028,033~,3,~2WD Double Cab 144.2"~,~SLT~,6,4,~N~,~S~,~N~,~S~,~N~,~N~,~N~,~~,~ ~,~Confirmed~,~w2015k65m22t5~,~Sierra 2500HD~,~Double Cab Standard Box 2-Wheel Drive SLT~,~Rear Wheel Drive~,~Extended Cab Pickup - Standard Bed~

Nach der Bereinigung brauche ich die Datei so:

364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043|005|006|007|003|008|016|041|012|029|068|027|028|033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

Ich habe sed -i -e mit mehreren Optionen ausprobiert, aber die Ausgabe ist nicht 100 % richtig.

Ich habe Folgendes versucht, aber es bringt nicht das gewünschte Ergebnis

sed -i -e 's/,~/|/g' file_name
sed -i -e 's/~,/|/g' file_name
sed -i -e 's/~//g' file_name
sed -i -e 's/\([0-9],[0-9]\)/|/g' file_name
sed -i -e 's/\r//g' file_name

Antwort1

ESC=$(printf '\033')
RED="${ESC}[0;31m"
 NC="${ESC}[0m"

sed -e '
   /./!b
   /[^[:space:]]/!b

   s/.*/\
&,/

   :loop
      h
      s/\(\n\),/|\1/;                                                  # An empty field
      s/\(\n\)\([+-]\{0,1\}[.][0-9]\{1,\}\),/\2|\1/;                   # +-.NNN
      s/\(\n\)\([+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}\),/\2|\1/;  # +-NNN.MMM +-NNN. +-NNN
      s/\(\n\)~\([0-9][0-9]*\),/\2|\1/;                                # ~NNN
      s/\(\n\)\([0-9][0-9]*\)~,/\2|\1/;                                # NNN~
      s/\(\n\)~\([^~]*\)~,/\2|\1/;                                     # ~...~
      x;G
      /^\(.*\)\n\1$/{
         g;'"s/\n\([^,]*\)/${RED}\1${NC}/"'
         i\
***'"${RED}ERROR${NC}"'*** Unable to process the field shown colored.\
\
Cause of error: What this means is that this particular field is not \
\
           Fix: You should add to the sed code in the :loop label to \
                digest the able to be processed by the sed code as it stands.\
\
The record with the offending field shown colored red:\

         q
      }
      g; # all clear: recover and carry on...
   /\n$/!bloop

   s/..$//
' csv.data

Arbeiten

  • Wir basieren die Lösung auf den verschiedenen Feldtypen.
  • Überspringen Sie leere oder leere Zeilen.
  • Fügen Sie ein „“, an, um den verwendeten regulären Ausdruck zu vereinfachen. Wir entfernen es am Ende.
  • Um den Ball ins Rollen zu bringen, platzieren wir einen Marker \nam Anfang der Zeile. Dieser Marker wandert von links nach rechts und springt dabei jeweils ein Feld weiter.
  • Die Aktion beginnt in der do-whileSchleife, in deren Hauptteil wir jeweils ein Feld verarbeiten. Der Feldanfang wird durch signalisiert \nund wir verarbeiten die verschiedenen Arten von Feldern, die auftreten können. Jedes Mal verschieben wir das verarbeitete Feld nach links von \nund ersetzen das ,durch ein |.
  • Die Schleife stoppt, wenn der Marker \ndas Zeilenende erreicht /\n$/, und wir entfernen dann den Marker sowie den Dummy, den ,wir am Anfang platziert hatten.

Ergebnisse

364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043|005|006|007|003|008|016|041|012|029|068|027|028|033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

Antwort2

Ich würde vorschlagen, einen dedizierten CSV-Parser wie den von Perl zu verwenden.Text::CSV

perl -MText::CSV -lne '
    BEGIN{ $csv = Text::CSV->new({ quote_char => "~" , escape_char => "~" , allow_whitespace => 1}) } 
    print join "|", $csv->fields() if $csv->parse($_)
  ' file_name
364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043,005,006,007,003,008,016,041,012,029,068,027,028,033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

verwandte Informationen