使用awk实现多列线性插值的问题求助
问题描述
现有如下格式的数据文件:
1 3 2 3 5 2 3 2 4 3 3 3 2 2 4 4 3 2 2 -6 5 3 2 2 -4
需要对每一列进行线性插值,在每两行之间插入4个插值点。例如第一列的输出格式如下:
1 i1 i2 i3 i4 2 i1 i2 i3 i4 3 i1 i2 i3 i4 4 i1 i2 i3 i4 5
已编写的单列处理awk脚本运行正常:
#!/bin/sh awk '{ y2 = $1 if (NR > 1) { steps = NR - prev_line_nr step_size = (y2 - y1) / (5 * steps) for (i = 1; i < 5 * steps; i++) { interpolated_value = y1 + i * step_size print interpolated_value } } prev_line_nr = NR print y2 y1 = y2 }' input_file
但修改为处理所有列的脚本无法正常工作,多列脚本如下:
awk '{ for (j = 1; j < 5 * steps; j++) { y2=$j if (NR > 1) { steps = NR - prev_line_nr step_size = (y2 - y1) / 5 * steps) for (i = 1; i < 5 * steps; i++) { interpolated_value = y1 + i * step_size print interpolated_value } } prev_line_nr = NR print y2 y1 = y2 } }' input_file
期望的输出格式如下:
1 3 2 3 5 1.2 3 2 3.2 4.6 1.4 3 2 3.4 4.2 1.6 3 2 3.6 3.8 1.8 3 2 3.8 3.4 2 3 2 4 3 2.2 3 2 3.6 3.2 2.4 3 2 3.2 3.4 2.6 3 2 2.8 3.6 2.8 3 2 2.4 3.8 3 3 2 2 4 3.2 3 2 2 2 3.4 3 2 2 0 3.6 3 2 2 -2 3.8 3 2 2 -4 4 3 2 2 -6 4.2 3 2 2 -5.6 4.4 3 2 2 -5.2 4.6 3 2 2 -4.8 4.8 3 2 2 -4.4 5 3 2 2 -4
需要修改脚本实现多列的线性插值处理。
修改后的多列插值脚本
以下是修正后的awk脚本,可实现多列线性插值,在每两行间插入4个插值点:
#!/bin/sh awk '{ # 保存当前行所有列的值 for (j = 1; j <= NF; j++) { curr[j] = $j } if (NR > 1) { # 生成4个插值行 for (i = 1; i <= 4; i++) { # 计算当前插值比例 ratio = i / 5.0 # 逐列计算插值并拼接输出 line = "" for (j = 1; j <= NF; j++) { val = prev[j] + ratio * (curr[j] - prev[j]) # 格式化输出,保持对齐 line = line sprintf("%.1f\t", val) } # 去除末尾多余制表符后打印 sub(/\t$/, "", line) print line } } # 打印当前行 print $0 # 保存当前行数据和行号 for (j = 1; j <= NF; j++) { prev[j] = curr[j] } prev_nr = NR }' input_file
关键修改说明
- 数据存储优化:改用数组
prev和curr分别保存上一行和当前行的所有列数据,避免单列处理的变量复用冲突。 - 插值逻辑简化:直接按每两行间插入4个点的需求循环4次,用
i/5的比例计算插值,逻辑更直观,避免原脚本的步骤计算混乱。 - 行输出对齐:逐列计算插值后拼接成完整行,用
sprintf控制小数位数,并用制表符分隔,保证输出格式与期望一致。 - 语法错误修复:修正原脚本循环逻辑混乱、括号不匹配等问题,调整执行顺序为先处理插值再打印当前行。
内容的提问来源于stack exchange,提问作者Kay
相关产品推荐
相关产品推荐

