Ich führe ein Shell-Skript aus, das einen Auslastungstest für meinen Dienst durchführt. Am Ende des Tests erhalte ich eine Datei, die folgendermaßen aussieht:

200    2.691
200    2.735
404    1.997
404    2.838
200    1.394
200    1.833

Ich möchte die minimale, maximale und mittlere Antwortzeit für jeden eindeutigen HTTP-Antwortcode berechnen. Etwas wie das -

http    min    max    mean    count
200    1.394  2.735   2.163    4
404    1.997  2.838   2.418    2

Die Ausgabe stammt von diesem Befehl (wenn das hilft):

curl -s -o /dev/null -w "%{http_code}\t%{time_total}\n" $SERVICE_URL

Kann jemand Hinweise geben, wie ich dies in Bash erreichen kann? Ich habe mir http://cacodaemon.de/index.php?id=11 angesehen für Ideen, konnte aber nichts zum Laufen bringen.

Vielen Dank.

5
AngryPanda 19 Apr. 2018 im 03:19

4 Antworten

Beste Antwort
$ cat tst.awk
{
    min[$1] = ( ($1 in min) && (min[$1] < $2) ? min[$1] : $2 )
    max[$1] = ( ($1 in max) && (max[$1] > $2) ? max[$1] : $2 )
    sum[$1] += $2
    cnt[$1]++
}
END {
    print "http", "min", "max", "mean", "cnt"
    for (key in cnt) {
        print key, min[key], max[key], sprintf("%.3f",sum[key]/cnt[key]), cnt[key]
    }
}

$ awk -f tst.awk file | column -t
http  min    max    mean   cnt
200   1.394  2.735  2.163  4
404   1.997  2.838  2.417  2

Das Obige funktioniert mit jedem awk in jeder Shell auf jeder UNIX-Box.

3
Ed Morton 19 Apr. 2018 im 00:58

Nach Leerzeichen kolumnieren -W Nach Spalte 1 gruppieren -g 1, Ausgaben für Spalte 2 basierend auf der Gruppierung drucken:

datamash -sW -g 1 min 2 max 2 mean 2 count 2 <dmInput

Um mehr von dem zu sehen, was los ist:

datamash --header-out -sW -g 1 min 2 max 2 mean 2 count 2 <dmInput | column -t

Und ... wenn Sie wirklich awk verwenden möchten, können Sie damit Spaltennamen hinzufügen:

awk 'BEGIN {print "HttpCode ResponseTime";} {print}' dmInput | datamash -sWH -g HttpCode min ResponseTime max ResponseTime mean ResponseTime count ResponseTime | column -t
1
zzxyz 19 Apr. 2018 im 00:56

Hier ist das Basis-Perl (kein CPAN erlaubt, da ich zu diesem Zeitpunkt nur meine Datamash-Antwort verwende), das Eds Antwort entspricht. Wie bereits erwähnt, in jeder Hinsicht nur ein kleines bisschen böser:

£ cat tst.pl
$min{$F[0]} = $F[1] if !(exists $min{$F[0]}) || $F[1] < $min{$F[0]};
$max{$F[0]} = $F[1] if !(exists $max{$F[0]}) || $F[1] > $max{$F[0]};
$sum{$F[0]} += $F[1]; 
$cnt{$F[0]}++;
END
{
      print "http min max mean cnt";
      for $key (keys %cnt) 
           {print "$key $min{$key} $max{$key} @{[$sum{$key}/$cnt{$key}]} $cnt{$key}";}
}
£ perl -lan tst.pl dmInput | column -t
http  min    max    mean     cnt
404   1.997  2.838  2.4175   2
200   1.394  2.735  2.16325  4
0
zzxyz 19 Apr. 2018 im 02:04

Verwenden Sie ein awk-Array

cat 1.txt | nawk '{s[$1]+=$2;c[$1]++;max[$1]=max[$1]>$2?max[$1]:$2;min[$1]=min[$1]==0?$2:min[$1]>=$2?$2:min[$1]} END{for(i in s) print i","min[i]","max[i]","s[i]/c[i]","c[i]}'  | sort
200,1.394,2.735,2.16325,4
404,1.997,2.838,2.4175,2
-1
R.Liu 19 Apr. 2018 im 02:04