Bash脚本替换CSV二值字段为0/1时文件未更新问题排查
问题说明
需要使用Bash处理CSV文件,将文件内的二值分类字段替换为0/1数值,待处理CSV结构如下:
age,sex,bmi,smoker,region,charges 19,female,27.9,yes,southwest,16884.924 23,male,29.83,no,northeast,1725.5523
原有执行命令为./b.sh insurance.csv,执行无报错但文件内容未更新。
原代码的错误点
- 语法错误:代码末尾多了一个多余的闭合大括号
},属于无效语法 - 逻辑缺失:仅修改了内存中
values数组的元素值,没有将修改后的内容输出或写回文件,原文件自然不会产生任何变化 - 索引错误:Bash数组下标从0开始计数,对应字段位置:0=age、1=sex、2=bmi、3=smoker、4=region、5=charges,原代码写的
${values[4]}实际匹配的是region字段,根本无法命中smoker字段的yes/no值 - 副作用风险:全局设置
IFS=,会改变整个脚本后续的字段分隔规则,容易引发其他未知问题 - 写回风险:如果直接读取原文件同时写入原文件,会导致文件被提前截断清空,必须通过临时文件中转。
修正后可用代码
#!/bin/bash filename="$1" if [ ! -f "$filename" ]; then echo "目标文件不存在" exit 1 fi tmpfile=$(mktemp) while IFS=, read -ra values; do # 替换sex字段 case "${values[1]}" in male) values[1]=0 ;; female) values[1]=1 ;; esac # 替换smoker字段(下标为3) case "${values[3]}" in yes) values[3]=1 ;; no) values[3]=0 ;; esac # 拼接为逗号分隔的行写入临时文件 echo "${values[*]}" | tr ' ' ',' >> "$tmpfile" done < "$filename" # 替换原文件 mv "$tmpfile" "$filename"
给脚本添加执行权限后运行即可完成替换,处理后的文件内容如下:
age,sex,bmi,smoker,region,charges 19,1,27.9,1,southwest,16884.924 23,0,29.83,0,northeast,1725.5523
提示:该方案仅适用于无引号包裹、字段内不含逗号的简单CSV结构,如果是复杂CSV建议使用专门的CSV处理工具比如
csvkit。
内容的提问来源于stack exchange,提问作者CPG
相关产品推荐
相关产品推荐

