Substitua o arquivo delimitado por vírgula por pipe, mas não remova vírgula ou aspas etc dentro do campo de qualificador de texto; no entanto, remova o qualificador de texto!

0

Meu arquivo é um arquivo delimitado por vírgula e o qualificador de texto é ~, mas minha exigência é localizar e substituir o arquivo delimitado por vírgulas por um arquivo delimitado por | (pipe) e remover o qualificador de texto ~ sem nada, no entanto, Eu não devo remover aspas ou aspas duplas ou qualquer caractere especial dentro dos dados presentes no qualificador de texto. eg: ~ abc ", ~ eu preciso disso como abc",

Abaixo está o conteúdo do meu arquivo de origem e da maneira que eu espero que o arquivo de saída ou manipulado seja.

Arquivo de origem:

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~

Após a limpeza, preciso do arquivo assim:

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

Eu tentei sed -i -e com várias opções, mas a saída não está 100% correta.

Eu tentei seguir, mas não está dando o resultado certo que eu queria

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
    
por Sudheer 26.05.2017 / 22:40

2 respostas

2

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

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

   s/.*/\
&,/

   :loop
      h
      s/\(\n\),/|/;                                                  # An empty field
      s/\(\n\)\([+-]\{0,1\}[.][0-9]\{1,\}\),/|/;                   # +-.NNN
      s/\(\n\)\([+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}\),/|/;  # +-NNN.MMM +-NNN. +-NNN
      s/\(\n\)~\([0-9][0-9]*\),/|/;                                # ~NNN
      s/\(\n\)\([0-9][0-9]*\)~,/|/;                                # NNN~
      s/\(\n\)~\([^~]*\)~,/|/;                                     # ~...~
      x;G
      /^\(.*\)\n$/{
         g;'"s/\n\([^,]*\)/${RED}${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

Trabalhando

  • Baseamos a solução nos vários tipos de campos.
  • Ignorar linhas vazias ou em branco.
  • Anexar um "," para simplificar o regex usado, vamos removê-lo no final.
  • Para definir a bola rolando, colocamos um marcador, \n , no início da linha. Este marcador viajará da esquerda para a direita, pulando um campo processado por vez.
  • A ação começa no loop do-while , no corpo do qual, processamos um campo por vez. O início do campo é sinalizado por \n e processamos as diversas variedades de campos que podem ocorrer. Toda vez, trazemos o campo processado para a esquerda de \n e substituímos o , por | .
  • O looping pára quando o marcador \n atinge o final da linha /\n$/ e depois tiramos o marcador, assim como o manequim , que colocamos no começo.

Resultados

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
    
por 27.05.2017 / 11:49
1

Eu sugiro usar um analisador CSV dedicada, como Texto de perl: : 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
    
por 27.05.2017 / 00:27