Regex para unir campos em um CSV

1

Eu tenho um CSV com mais de 2 milhões de registros com o seguinte formato.

path;name;extension;size;date;user    
/foo/;difacs;cgi;3,795;18-07-2011;Unix User\pads
/foo/;difacs.cgi;bak;2,622;03-12-2009;Unix User\pads
/foo/test/kzt/netcdfSample/testing/;zzz;;401;27-07-2006;Unix User\kzt
/foo/test/kzt/netcdfSample/vic_netcdf_popup/;a;txt;1,832;17-02-2006;Unix User\kzt

Eu preciso juntar o caminho, o nome e a extensão em um campo formatado corretamente.

path;size;date;user    
/foo/difacs.cgi;3,795;18-07-2011;Unix User\pads
/foo/difacs.cgi;bak;2,622;03-12-2009;Unix User\pads
/foo/test/kzt/netcdfSample/testing/zzz/;401;27-07-2006;Unix User\kzt
/foo/test/kzt/netcdfSample/vic_netcdf_popup/a.txt;1,832;17-02-2006;Unix User\kzt

Obrigado antecipadamente!

    
por StefWill 04.06.2012 / 07:36

1 resposta

1

Esta é uma variação da resposta do slhck que lida corretamente com um campo de extensão vazio (e evita a substituição falsa de um ponto que possa ter existido intencionalmente no segundo ou terceiro campo):

sed 's/^\([^;]*\);\([^;]*\)//;ta;:a;s/^[^;]\+;;/&/;t;s/;/./' inputfile

Não é necessário usar um terceiro grupo de captura. Essa resposta funciona sem ela. Não é necessário escapar do ponto no lado direito do comando substituto.

Aqui está uma explicação do meu script:

  • capture os dois primeiros campos, excluindo os pontos e vírgulas que os delimitam.
  • ta;:a - se um substituto for bem-sucedido, então ramifique para o rótulo :a que imediatamente se segue - isso efetivamente limpa o sinalizador "sucesso"
  • s/^[^;]\+;;/&/ - substitui uma sequência de semicolons seguida por dois pontos e vírgulas (os primeiro e segundo campos concatenados seguidos por um terceiro campo vazio) consigo mesmo - é um não-op, mas define o sinalizador "sucesso".
  • t - se a última substituição foi bem sucedida (o terceiro campo está vazio), pule para o final do processamento da linha atual (já que nenhum rótulo foi especificado)
  • s/;/./ - se chegamos a este ponto (o terceiro campo não estava vazio ), substitua o ponto-e-vírgula por um ponto.
por 04.06.2012 / 15:17