Bash读取可变表头CSV 动态映射列生成固定格式CSV方案
可变结构CSV标准化处理实现方案
需求背景
待处理CSV文件结构无固定规则,不会提前告知结构变更:
- 标准表头为
No,Latitude,Longitude,Name,Altitude,Satellites,Date,Time - 可能出现
Satellites列缺失、Name列缺失或两列均缺失的情况,总列数在5-8列浮动 - 最终需要输出固定表头为上述标准字段的标准化CSV文件,自动识别每一列的实际含义完成映射
原有实现思路
原方案通过表头匹配构建列映射再逐行转换,核心逻辑可行,实现步骤如下:
- 读取源文件表头存入数组
a,读取目标固定表头存入数组b
读取源表头代码:
读取目标固定表头代码:IFS=",";read -r a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10] a[11]IFS=",";read -r b[1] b[2] b[3] b[4] b[5] b[6] b[7] <<< "No,Latitude,Longitude,Name,Altitude,Satellites,Date,Time" - 遍历数组
a的非空元素,与数组b的表头做匹配,记录源列序号到目标列的映射关系do for x in [1..7] do if [[ ${a[i]} = ${b[x]} ]] then # 源文件第i列对应输出文件第x列 output[$x]=$i fi done done - 逐行读取源文件内容,按照映射关系将对应列写入新文件,生成标准化CSV
IFS=","; while read -r a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10] a[11] do echo "${a[output[1]]}, ${a[output[2]]},${a[output[3]]},${a[output[4]]},${a[output[5]]},${a[output[6]]},${a[output[7]]}" >> new.csv done < source.csv
原有代码存在几处可修正的细节:
- 硬编码固定读取11列的逻辑,若源文件列数超出预设值会出现字段截断
- 列匹配循环中
[1..7]不符合bash语法,正确序列遍历应使用{1..7},且原代码缺失外层遍历源表头的i变量迭代逻辑- 循环内逐行打开文件追加写入,大文件场景下IO开销高
- 未做缺失列的兼容处理,列不存在时容易出现数组下标报错
优化实现方案
不需要硬编码数组长度、不需要双层循环匹配,利用bash关联数组可以实现更简洁健壮的转换逻辑:
#!/bin/bash # 定义固定输出的表头顺序,后续调整字段顺序只需要修改这个数组 target_headers=("No" "Latitude" "Longitude" "Name" "Altitude" "Satellites" "Date" "Time") # 读取源文件表头,自动拆分到数组,不需要预设列数 IFS=, read -r -a source_headers < source.csv # 构建关联映射:key=表头名称,value=该字段在源文件中的列索引 declare -A col_map for idx in "${!source_headers[@]}"; do col_map[${source_headers[$idx]}]=$idx done # 先写入输出文件的固定表头 (IFS=,; echo "${target_headers[*]}") > new.csv # 跳过源文件表头行,逐行处理数据 tail -n +2 source.csv | while IFS=, read -r -a row; do output_row=() for header in "${target_headers[@]}"; do # 源文件存在对应列就取值,不存在则自动补空值 output_row+=("${row[${col_map[$header]:-}]:-}") done (IFS=,; echo "${output_row[*]}") done >> new.csv
优化点说明
- 无硬编码列数限制,自动适配源文件列数变化,后续源文件新增字段也不会出现截断问题
- 用关联数组直接存储表头和列索引的对应关系,省去冗余的双层循环匹配
- 缺失字段自动补空,不会出现数组下标报错,输出CSV格式完全符合规范
- 把文件追加重定向放到循环外部,减少文件打开关闭次数,大文件处理效率提升明显
- 可维护性强,后续需要调整输出字段、增减字段只需要修改
target_headers数组即可
内容的提问来源于stack exchange,提问作者a9993923942
相关产品推荐
相关产品推荐

