我有一个带有长变量字符串的日志,我试图从一个数字中获取最小值、最大值和平均值。
字符串示例
date time from Time: 100 ms to status code:
date time Time: 1050 ms status code IP
date time IP Time: 2 ms status code destination
“时间:* ms”在每一行中都是恒定的,但字段位置正在变化。我需要最大、最小和平均值的毫秒数。
答案1
使用 GNU awkFPAT
(“一个正则表达式(作为字符串)告诉 gawk 根据与正则表达式匹配的文本创建字段。”):
awk -v FPAT='Time:[[:blank:][:digit:]]+ms' '
{ split($1, tmp); sum+=tmp[2] }
NR==1 { min=max=tmp[2] }
min>tmp[2]{ min=tmp[2] }
max<tmp[2]{ max=tmp[2] }
END{ print min, max, sum/NR }' infile
输出;
2 1050 384
答案2
执行此操作的一种方法是循环遍历每行中的所有字段,获取“ms”的字段编号,然后从该字段编号中减去一,这将得到您的数字的字段编号。只要数字始终是 ms 之前的字段(我认为这就是您所说的),那么这就会起作用。
这是打印每个数字的示例。
awk '{for(i-1;i<=NF;++i){if($i == "ms"){print $(i-1)}}}' filename
如果你想获得数字的最小值、最大值和平均值,那么你将需要做更多的事情。
awk '
{for(i=1;i<=NF;++i){
if($i == "ms")
{
if(NR == 1)
{min=max=$(i-1)};
if($(i-1) > max)
{max=$(i-1)};
if($(i-1)<min)
{min=$(i-1)};
sum=sum+$(i-1);
count+=1;
}
}
}
END{
average=sum/count;
print "min: "min;
print "max: "max;
print "sum: "sum;
print "average: "average;
}
输出:
min: 2
max: 1050
sum: 1152
average: 384
答案3
和awk我们首先从每条记录中找出毫秒数,将其强制为数字,然后更新运行总和。
awk '
p=match($0, /Time: [0-9]+ ms/){
sum += ms = substr($0,p+6,RLENGTH-9)+0
}
ms>max{max=ms}
min==""||ms<min{min=ms}
END{print min, max, sum/NR}
' file
输出
2 1050 384
答案4
命令
最大值:
awk '{for(i=1;i<=NF;i++){if($i ~ /ms/){print $(i-1)}}}' filename| awk 'NR==1{sum=$1}($1 > sum){sum=$1}END {print sum}'
输出
1050
最小值:
awk '{for(i=1;i<=NF;i++){if($i ~ /ms/){print $(i-1)}}}' filename| awk 'NR==1{sum=$1}($1 < sum){sum=$1}END {print sum}'
输出
2