긴 변수 문자열이 포함된 로그가 있고 숫자에서 최소, 최대 및 평균을 얻으려고 합니다.
문자열 예
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
이를 수행하는 한 가지 방법은 각 행의 모든 필드를 반복하여 "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