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

基于ID比对两文件列差值并追加至File A行尾的技术求助

AWK文件差值计算输出异常修复方案

问题背景

现有两个数据文件:

  • File A:包含同一ID的多行数据,示例如下:
01  20200111  28.56  22.07  40.14  49.79  22.81  49.31  33.75  31.24  39.41  36.18
02  20200118  32.41  14.89  38.82  60.54  11.54  49.10  34.34  25.53  36.96  34.30
03  20200125  21.95  18.48  28.45  42.94  22.45  42.40  36.43  34.53  43.51  33.28
...
01  20210109  29.32  24.60  34.41  46.56  29.38  44.06  34.47  33.75  41.12  36.04
02  20210116  29.38  28.39  33.07  42.63  29.46  39.41  32.45  33.60  43.81  34.93
03  20210123  27.51  19.55  32.98  45.88  26.05  46.88  37.58  31.98  44.52  35.90
  • File B:每个ID仅一行基准数据,示例如下:
01  19912020  24.20  16.70  31.28  45.98  19.26  42.57  33.43  29.35  39.96  32.22
02  19912020  24.29  15.46  29.02  44.47  19.24  40.57  32.98  29.80  40.26  31.36
03  19912020  20.69  14.07  29.90  45.89  21.34  44.71  35.90  31.61  42.00  33.08

需求:将File A每行第3-12列的值,减去File B中对应ID行的第3-12列值,把差值追加到File A对应行末尾。输出的第3-22列需按%8.2f格式显示。

用户尝试了以下AWK代码,但输出中ID内容在File A和File B间交替,无法得到正确结果:

awk '
FNR==NR { for (i=3;i<=NF;i++)                    # 1st file: loop through 3rd-12th fields
              b[$1][i]=$i                        # store field values in 2-dimensional array
          next                                   # skip to next input line
        }
$1 in b { printf "%s %s%s", $1, OFS, $2           # 2nd file: if $1 is index in first dimension of array b[] then printf first 2 fields and then ...
          for (i=3;i<=NF;i++)                    # loop through 3rd-12th fields
              printf "%s%8.2f%8.2f", OFS, $i,$i-b[$1][i]    # print the difference
          print ""                               # terminate the current line of output
        }

错误原因

  1. 文件输入顺序错误:代码逻辑是先读取第一个文件存储基准数据,再处理第二个文件计算差值。用户大概率是把File A作为第一个输入文件、File B作为第二个,导致基准数据存储的是File A的内容,后续处理File B时输出了B的行和错误差值,最终出现交替输出。
  2. 格式输出不严谨:原代码中前两列的输出未按要求的固定间距格式化,可能导致排版混乱。

修正后的AWK代码

awk '
# 读取File B(基准文件),存储每个ID的第3-12列数据
FNR == NR {
    for (i = 3; i <= 12; i++) {
        base[$1][i] = $i
    }
    next
}
# 处理File A(目标文件),计算并追加差值
$1 in base {
    # 格式化输出前两列:ID占2位,日期占8位,保持固定间距
    printf "%2s   %8d", $1, $2
    # 输出第3-12列的原始值,以及对应差值
    for (i = 3; i <= 12; i++) {
        printf "%8.2f%8.2f", $i, $i - base[$1][i]
    }
    print ""
}
' FileB FileA

代码说明

  • 文件顺序:必须将File B作为第一个输入文件,确保先读取基准数据存入数组base。
  • 字段范围:明确循环范围为3到12,避免处理多余字段。
  • 格式化输出:前两列用固定宽度格式化,第3-22列严格按%8.2f输出,保证排版对齐。
  • 差值计算:对每个字段计算File A值 - File B对应值,直接追加到该行后面。

运行示例

执行命令后,输出将符合需求格式,示例如下:

01   20200111    28.56  22.07  40.14  49.79  22.81  49.31  33.75  31.24  39.41  36.18   4.36   5.37   8.86   3.81   3.55   6.74   0.32   1.89  -0.55   3.96
02   20200118    32.41  14.89  38.82  60.54  11.54  49.10  34.34  25.53  36.96  34.30   8.12  -0.57   9.80  16.07  -7.70   8.53   1.36  -4.27  -3.30   2.94
03   20200125    21.95  18.48  28.45  42.94  22.45  42.40  36.43  34.53  43.51  33.28   1.26   4.41  -1.45  -2.95   1.11  -2.31   0.53   2.92   1.51   0.20
...
01   20210109    29.32  24.60  34.41  46.56  29.38  44.06  34.47  33.75  41.12  36.04   5.12   7.90   3.13   0.58  10.12   1.49   1.04   4.40   1.16   3.82

内容的提问来源于stack exchange,提问作者ncwxpanther

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:15:04