Search code examples
linuxshellunixawktraceroute

Script to extract and find min, max and avg from a file using a shell script from traceroute output


I am creating a shell scrip to store the output of the traceroute command with a user-entered input to a file.

I want to extract the latency for each packet and each router and find the min, max and average times for each packet.

If this is the output of traceroute:

1  176.221.87.1 (176.221.87.1)  1.474 ms  1.444 ms  1.390 ms
2  f126.broadband2.quicknet.se (92.43.37.126)  10.047 ms  19.868 ms  23.156 ms
3  10.5.12.1 (10.5.12.1)  24.098 ms  24.340 ms  25.311 ms

I need to find the max of all latency for the first packet, which is in this case 24.098 ms. Similarly min is 1.474 and average for the first packet is 11.873 ms. I need to do this for each packet.

I want output like:

1  176.221.87.1 (176.221.87.1)  1.474 ms  1.444 ms  1.390 ms
2  f126.broadband2.quicknet.se (92.43.37.126)  10.047 ms  19.868 ms  23.156 ms
3  10.5.12.1 (10.5.12.1)  24.098 ms  24.340 ms  25.311 ms

For the first packet:

Minimum: 1.474 ms
Maximum: 24.098 ms
Average: 11.873 ms

.
.

and so on.

I am not able to come up with an awk statement to do this. Perhaps there is another way?

Any inputs would be really helpful.


Solution

  • If my understanding is correct, you want something like this

        NR == 1 {
                n = $4                   # set min to first value
                u = $5                   # keep time unit for later
        }
    
        {
                s += $4
                c++
                if ($4 > m) {            # update max
                        m = $4
                }
                if ($4 < n) {            # update min
                        n = $4
                }
        }       
    
        END {
                print "Minimum: " n, u "\nMaximum: " m, u "\nAverage: " s / c, u
        }
    

    For all three columns, you can extend this easily

        NR == 1 {
                split("4,6,8",ix,",")
                for(i in ix) n[ix[i]] = $(ix[i])
                u = $5
        }
    
        {
                c++
                for(i in ix) {
                     p = ix[i];
                     s[p] += $(p)
                     if ($p > m[p]) m[p] = $p
                     if ($p < n[p]) n[p] = $p
                }
        }
    
        END {
                mins = "Minimum ("u"):"
                maxs = "Maximum ("u"):"
                avgs = "Average ("u"):"
                for(i in ix) {
                      mins = mins FS n[ix[i]]
                      maxs = maxs FS m[ix[i]]
                      avgs = avgs FS s[ix[i]]/c
                }
                print mins
                print maxs
                print avgs
        }
    

    Should print

    Minimum (ms):  1.474 1.444 1.390
    Maximum (ms):  24.098 24.340 25.311
    Average (ms):  11.873 15.2173 16.619