Bash 使用awk打印列中的某些参数

Bash 使用awk打印列中的某些参数,bash,awk,Bash,Awk,我遇到了一个小问题,我无法用bash脚本中的awk解决这个问题 我确实有以下数据文件: 33 1000 1.108932e-01 2.825803e+00 -9.955642e-05 0.0000e+00 0.0000e+00 8.012180e-02 4.081916e-02 0.0000e+00 7.8557e-01 6.1128e+01 4.0468e+00 -9.9558e-05 3.8526e-02 3.1874e-03

我遇到了一个小问题,我无法用bash脚本中的awk解决这个问题

我确实有以下数据文件:

 33   1000   1.108932e-01   2.825803e+00  -9.955642e-05    0.0000e+00       0.0000e+00    8.012180e-02 4.081916e-02

 0.0000e+00   7.8557e-01   6.1128e+01   4.0468e+00  -9.9558e-05   3.8526e-02   3.1874e-03   5.1303e-01   0.0000e+00

 1.6667e-02   7.8530e-01   6.0977e+01   4.0552e+00   1.0627e-01   7.8951e-02   6.2521e-03   5.0750e-01   0.0000e+00

...
它有一个包含10个元素的标题行,后面是一个包含33行和9列的数组

我想使用此文件中的数据打印出标题行中的第四个参数,后跟第3行的平均值(即
sum+=$3/{Number of lines}
)。目前,我试着这样做:

gawk '{time=FNR==1{$4};if(NR>1)sum+=$3}; time = FNR == 1{$4} END {sum=sum/(NR-1); print time " " sum}' $tmpn.data >> $tmpn.vrms
它对平均值很有效,但是,时间参数不正确,我只得到0作为返回值。也许我只遗漏了一件小事,但不幸的是,我在网上找不到任何东西。解决这个问题的最好办法是什么

谢谢你的帮助

干杯。

试试:

awk 'NR==1 {time=$4;next} {sum+=$3} END {print time, (sum/(NR-1))}' $tmpn.data >>$tmpn.vrms
  • NR==1{time=$4;next}
    是一个模式动作对:

    • 模式(条件)
      NR==1
      仅对第一个输入行有效
    • 因此,操作
      {time=$4;next}
      只对第一行执行,它将头的第四个字段存储在变量
      time
      中,然后继续下一条记录(第行;
      next
  • {sum+=$3}
    对所有剩余记录(即数据记录)进行处理,并对变量
    sum
    中第三个字段中的值进行迭代求和

  • 结束{打印时间,(总和/(NR-1))}

    • 处理完所有输入记录后,执行
      END
    • {print time,(sum/(NR-1))}
      打印标题字段和第三个字段值的平均值,由默认的输出字段分隔符(
      OFS
      )分隔,该分隔符是一个空格。请注意,
      NR
      包含
      END
      块内输入记录的总数

关于您的解决方案尝试和
awk
理念的说明

  • 如(当前)所述,您的命令中断,因为您已将整个脚本包含在
    {…}

  • 通常,
    awk
    的简洁优雅来自于一系列精心制作的图案动作对

    • 模式是一个条件(布尔表达式),仅当条件为真时才执行相关操作(一系列语句)
    • 将模式视为去除“语法噪音”的
      if
      语句的条件部分,将动作视为
      if
      语句的主体:
      {;…}
      在概念上是
      if(){;…}
  • 在给定的一对中,您可以省略动作或模式:

    • 如果忽略模式操作将无条件执行(尽管如果上一个模式操作对跳过了进一步的处理,例如使用
      下一个
      退出
      ,操作可能仍然无法执行)

    • 如果忽略操作默认操作是
      {print}
      ,即打印(可能修改的)当前记录

      • 此行为使常用速记
        1
        能够简单地打印当前记录:
        1
        是一种模式,在计算模式的布尔上下文中,该模式始终为true,并且在没有关联操作的情况下,默认情况下打印当前记录

awk中的另一个版本,使用
中的
getline
循环读取并检测文件结尾,然后输出头缓冲区
b
和平均值:

$ awk 'NR==1{b=$4; while(getline==1){s+=$3;c++} print b,s/c}' data
4th 40.7386
它希望
数据
文件有一个标题行。解释:

NR==1 {                  # read in the first line and ...
    b=$4                 # ... buffer the 4th field of the header 
    while(getline==1) {  # then read while there are records to read
        s+=$3            # sum up the values in the 3rd field
        c++              # count the number of values, add if($3!="") if needed
    } 
    print b, s/c         # after while output header and average
}

阅读Arnold Robbins的《有效的Awk编程》,第四版,开始学习Awk语法和语义。谢谢你的提示!非常感谢您的详细描述和解释。工作得很好。