我偶然发现了一个小问题,我无法用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作为返回。也许我只缺少一件小事,但不幸的是我无法在网上找到任何东西。什么是解决这个问题的最佳方法。
感谢您的帮助。
干杯。
答案 0 :(得分:3)
尝试:
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}
,并将标题的第4个字段存储在变量time
中,然后进入下一条记录(行; {{1 }})。 next
,为所有剩余记录(即数据记录)处理,迭代地汇总变量{sum+=$3}
中第3个字段中的值
sum
:
END {print time, (sum/(NR-1))}
块。END
打印标题字段和第3个字段值的平均值,由默认输出字段分隔符({print time, (sum/(NR-1))}
)分隔,这是一个空格。请注意,OFS
包含NR
块内的输入记录总数。 关于您的解决方案尝试的说明和END
的哲学:
正如(目前)所述,您的命令会中断,因为您已将整个脚本包含在awk
中。
通常, {...}
简洁优雅来自精心设计的模式动作的 序列 对。
awk
语句的条件部分,使用"语法噪音"删除,并将该操作作为if
语句的主体:if
1>}(概念上)是<pattern> { <action-cmd1>; ... }
在给定的一对中,您可以省略操作或模式:
如果您省略模式 ,则操作无条件执行 (尽管此操作可能如果之前的模式操作对跳过进一步处理(例如使用if (<pattern>) { <action-cmd1>; ... }
或next
),则仍然无法执行。
如果忽略操作 ,则默认操作为exit
,即打印(可能)当前记录。
{ print }
能够简单地打印当前记录:1
是一种模式,在评估模式的布尔上下文中,它始终为true,并且在如果没有相关的操作,默认情况下会打印当前记录。答案 1 :(得分:0)
awk中的另一个版本在getline
循环中使用while
来读取和检测文件结尾,然后输出标头缓冲区b
和平均值:
$ awk 'NR==1{b=$4; while(getline==1){s+=$3;c++} print b,s/c}' data
4th 40.7386
它希望data
文件有一个标题行。说明:
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
}