特定の平均計算[閉じる]

特定の平均計算[閉じる]

長い変数文字列を含むログがあり、数値から最小、最大、平均を取得しようとしています。

文字列の例

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

「Time:* ms」はすべての行で一定ですが、フィールドの位置は変わります。最大、最小、平均ミリ秒が必要です。

答え1

GNU awkの使用FPAT正規表現(文字列)は、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

これを行う1つの方法は、各行のすべてのフィールドを繰り返して「ms」のフィールド番号を取得し、そのフィールド番号から1を引くことです。これにより、その番号のフィールド番号が提供されます。数値が常に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 '
  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

関連情報