遍历 csv 并更改满足条件的列的值

Iterate over a csv and change the values of a column that meets a condition

我必须使用 bash 遍历 CSV 文件并替换满足条件的列的值。最后,结果必须存储在输出文件中。

我写了这段代码,它读取文件并将内容存储在一个数组中。在遍历文件时,如果第 13 列的值等于“NULL”,则必须将此记录的值替换为“0”。检查文件后,替换值的输出将存储在 file_b.

#!/bin/bash
file="./2022_Accidentalidad.csv"
while IFS=; read -ra array
do
    if [[ ${array[13]} == "NULL" ]]; then
    echo "${array[13]}" | sed -n 's/NULL/0/g' 
    fi
done < $file > file_b.csv

问题是 file_b 是空的。那里没有写任何东西。 我该怎么做?

我不能使用 AWK,必须使用 FOR 或 WHILE 命令遍历文件。

示例输入:

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

预期产出

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;0;NULL;443359,226;4472082,272;N;NULL

非常感谢。

awk也可以时:

awk 'BEGIN{FS=OFS=";"} NR==2 && =="NULL"{=0} {print}' "$file" > file_b.csv

参见:8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

你不需要sed。只需将 $array[13] 替换为 0。然后打印整个数组,在字段之间使用 ; 分隔符。

(             # in a subshell
    IFS=';'   # set IFS, that affects `read` and `"${array[*]}"`
    while read -ra array
    do
        if [[ ${array[13]} == "NULL" ]]; then
            array[13]=0
        fi
        echo "${array[*]}"
    done
) < $file > file_b.csv

echo 使用 $IFS 的第一个字符作为输出字段分隔符。

一个使用正则表达式和 BASH_REMATCH 数组的想法:

regex='(([^;]*;){13})(NULL)(;.*)'

while read -r line
do
    [[ "${line}" =~ $regex ]] && 
    line="${BASH_REMATCH[1]}0${BASH_REMATCH[4]}"

    # uncomment following line to display contents of BASH_REMATCH[] array
    # declare -p BASH_REMATCH

    echo "${line}"

done < file.csv > file_b.csv

这会生成:

$ cat file_b.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;0;NULL;443359,226;4472082,272;N;NULL