遍历 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
我必须使用 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