Regex para unir campos en un CSV

Regex para unir campos en un CSV

Tengo un CSV con más de 2 millones de registros con el siguiente 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

Necesito unir la ruta, el nombre y la extensión en un campo con el formato correcto.

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

¡Gracias de antemano!

Respuesta1

Esta es una variación de la respuesta de slhck que trata correctamente un campo de extensión vacío (y evita reemplazar falsamente un punto que podría haber existido intencionalmente en el segundo o tercer campo):

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

No es necesario utilizar un tercer grupo de captura. Esa respuesta funciona sin ella. No es necesario escapar del punto en el lado derecho del comando sustituto.

Aquí hay una explicación de mi guión:

  • captura los dos primeros campos, excluyendo los puntos y coma que los delimitan.
  • ta;:a- si se realizó un reemplazo exitoso, pase a la etiqueta :aque sigue inmediatamente; esto efectivamente borra la bandera de "éxito"
  • s/^[^;]\+;;/&/- reemplace una secuencia de puntos que no son punto y coma seguidos de dos puntos y coma (el primer y segundo campo concatenados seguidos por un tercer campo vacío) con sí mismo; no es una operación, pero establece el indicador de "éxito".
  • t- si el último reemplazo fue exitoso (el tercer campo está vacío), salte al final del procesamiento de la línea actual (ya que no se especificó ninguna etiqueta)
  • s/;/./- si hemos llegado a este punto (el tercer campo eranovacío), reemplace el punto y coma con un punto.

información relacionada