Bash 使用awk打印列中的某些参数
我遇到了一个小问题,我无法用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
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
是一种模式,在计算模式的布尔上下文中,该模式始终为true,并且在没有关联操作的情况下,默认情况下打印当前记录1
- 此行为使常用速记
- 如果忽略模式,操作将无条件执行(尽管如果上一个模式操作对跳过了进一步的处理,例如使用
中的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语法和语义。谢谢你的提示!非常感谢您的详细描述和解释。工作得很好。