You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:42:44