使用 sed 和正则表达式的 csv 列的数据类型

Data types from csv columns using sed and regex

我要为大学解决一个问题。我必须使用 bash 脚本来指示 csv 中每一列的数据类型。

这是 header 和 csv 的第一行

num_expediente;fecha;hora;localizacion;numero;cod_distrito;distrito;tipo_accidente;estado_meteorológico;tipo_vehiculo;tipo_persona;rango_edad;sexo;cod_lesividad;lesividad;coordenada_x_utm;coordenada_y_utm;positiva_alcohol;positiva_droga
2022S000001;01/01/2022;1:30:00;AVDA. ALBUFERA, 19;19;13;PUENTE DE VALLECAS;Alcance;Despejado;Turismo;Conductor;De 18 a 30 años;Mujer;NULL;NULL;443359,226;4472082,272;N;NULL

我正在使用 sed 命令来确定数据类型:

sed -rn '1p
    2s/[[:blank:]]//g
    2s/([[:digit:]]+:[[:digit:]]+:[[:digit:]]+)/(time)/g
    2s/([[:digit:]]+\/[[:digit:]]+\/[[:digit:]]+)/(date)/g
    2s/([[:digit:]]+,[[:digit:]]+)/(decimal)/g
    2s/([[:digit:]]+[[:alpha:]]+[[:digit:]]+)/(string)/g
    2s/([a-zA-Z]+\.[a-zA-Z]+,[0-9]+)/(string)/g
    2s/([[:digit:]]+)/(int)/gp' < $file

但并非所有字段都填充了正确类型的数据。这是我得到的输出

num_expediente;fecha;hora;localizacion;numero;cod_distrito;distrito;tipo_accidente;estado_meteorológico;tipo_vehiculo;tipo_persona;rango_edad;sexo;cod_lesividad;lesividad;coordenada_x_utm;coordenada_y_utm;positiva_alcohol;positiva_droga
(string);(date);(time);(string);(int);(int);PUENTEDEVALLECAS;Alcance;Despejado;Turismo;Conductor;De(string)años;Mujer;NULL;NULL;(decimal);(decimal);N;NULL

如何将粗体字段替换为(字符串)

我用过:

2s/([^(string)][a-zA-Z]+)/(string)/g

但是输出完全错误

num_expediente;fecha;hora;localizacion;numero;cod_distrito;distrito;tipo_accidente;estado_meteorológico;tipo_vehiculo;tipo_persona;rango_edad;sexo;cod_lesividad;lesividad;coordenada_x_utm;coordenada_y_utm;positiva_alcohol;positiva_droga
(string);((string));(ti(string));(string);(int);(int)(string)(string)(string)(string)(string)(string)(string)(string)(string)(string)(string);((string));((string))(string)(string)

预期输出为:

(string);(date);(time);(string);(int);(int);(string);(string);(string);(string);(string);(string);(string);(string);(string);(decimal);(decimal);(string);(string)

提前致谢

Awk 将是更好的选择,因为它可以轻松地将行拆分为字段 逐一检查字段:

awk -F';' -v OFS=';' '
    NR>1 {
        for (i = 1; i <= NF; i++) {
            if (sub(/^[0-9]+:[0-9]+:[0-9]+$/, "(time)", $i));
            else if (sub(/^[0-9]+\/[0-9]+\/[0-9]+$/, "(date)", $i));
            else if (sub(/^[0-9]+,[0-9]+$/, "(decimal)", $i));
            else if (sub(/^[0-9]+$/, "(int)", $i));
            else if (sub(/^.*[a-zA-Z].*$/, "(string)", $i));
        }
    }
1' input_file

输出:

num_expediente;fecha;hora;localizacion;numero;cod_distrito;distrito;tipo_accidente;estado_meteorologico;tipo_vehiculo;tipo_persona;rango_edad;sexo;cod_lesividad;lesividad;coordenada_x_utm;coordenada_y_utm;positiva_alcohol;positiva_droga
(string);(date);(time);(string);(int);(int);(string);(string);(string);(string);(string);(string);(string);(string);(string);(decimal);(decimal);(string);(string)

if .. else .. 语法将是必要的;否则一旦替换字符串, 比如(time),可以再换成(string)