如何用Linux Bash的sed为IGRA2气象数据行添加头部属性并转CSV
使用Bash Sed处理IGRA2气象数据并转换为CSV
刚好之前处理过类似的气象数据格式,用Sed完全可以实现你的需求——把每条#开头的头部属性(时间、经纬度等)追加到对应的气压层数据行,最终输出符合要求的CSV。下面是完整的实现方案,包括命令和详细解释:
完整Sed命令
sed -E ' # 先输出CSV表头 1i\ lvl12,etime,press,gph,temp,rh,dpdp,wdir,wspd,hour,lattitude,longitude # 处理#开头的头部行:提取小时、纬度、经度存到保持空间 /^#/ { # 匹配IGRA2头部格式:#ID 年 月 日 99 时分 数据源 经度 纬度 ... s/^#\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+([0-9]{2})\S+\s+\S+\s+\S+\s+(-?[0-9]+)\s+(-?[0-9]+)\s+.*/\1,\3,\2/ h b } # 修复数据里的连字符问题(比如750-9999 → 750 -9999) s/([0-9]+)-/\1 -/g # 把长数据行拆成每个气压层一行(每9个字段为一组) :split s/((\S+\s+){8}\S+)\s+/\1\n/g t split # 合并头部字段并转成CSV格式 G s/\s+/,/g s/\n/,/g ' input_data.txt > output.csv
命令分步解释
1. 输出CSV表头
第一部分先在文件开头插入你需要的CSV列名,确保输出的CSV结构清晰:
1i\ lvl12,etime,press,gph,temp,rh,dpdp,wdir,wspd,hour,lattitude,longitude
2. 提取并保存头部属性
针对每条#开头的头部行,我们提取小时(时分字段的前两位,比如0935取09)、纬度、经度,然后把这些值存到Sed的「保持空间」(相当于临时缓存),后续所有属于这个头部的行都能复用这些值:
/^#/ { s/^#\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+([0-9]{2})\S+\s+\S+\s+\S+\s+(-?[0-9]+)\s+(-?[0-9]+)\s+.*/\1,\3,\2/ h b }
h:把处理后的hour,latitude,longitude字符串存入保持空间b:直接跳到下一行,避免头部行被当成数据处理
3. 修复数据格式错误
原始数据里有750-9999这种格式错误(应该是750 -9999),这一步先修复,确保每个字段都是独立的:
s/([0-9]+)-/\1 -/g
4. 拆分长数据行为单个气压层记录
IGRA2的每个头部后面跟着一长串数据,对应多个气压层。我们把这串数据拆成每行对应一个气压层(每9个字段一组,匹配你目标CSV的前9列):
:split s/((\S+\s+){8}\S+)\s+/\1\n/g t split
:split:定义循环标签t split:只要还有可拆分的字段,就循环拆分,直到所有数据段都单独成行
5. 合并头部属性并转CSV
最后把保持空间里的头部属性追加到每个数据行末尾,然后把所有空格替换成逗号,完成CSV转换:
G s/\s+/,/g s/\n/,/g
G:把保持空间的头部值追加到当前数据行后面- 两个替换命令分别把空格和换行符换成逗号,得到标准的逗号分隔格式
注意事项
- 如果你的IGRA2数据段字段数量/顺序和目标CSV有差异,只要调整拆分时的字段数(比如把
{8}改成对应数字)和头部提取的正则即可。 - 如果数据里还有其他格式问题(比如更多特殊后缀),可以在修复步骤里加额外的正则替换。
- 示例里提取的是小时的整数部分,如果需要更精确的时间(比如把
0935转成9.58),可以修改头部提取的逻辑。
内容的提问来源于stack exchange,提问作者Srivatsa Sharma G
相关产品推荐
相关产品推荐

