How to add two temporary outputs in bash

I want to calculate in bash the average time spent by several teams. Time command output min: sec.milisec.

I do not know how to add two outputs of this kind in bash, and in the final - calculate the average value.

I tried converting the output with a date, but the output is "date: invalid date` 0: 01.00".

+4
source share
2 answers

This is the answer in three parts.

Part one

First, use the TIMEFORMAT variable to display only the elapsed seconds. Then you can add it directly

From man bash

TIMEFORMAT The value of this parameter is used as a format string that defines how time information for pipelines is prefixed with a reserved time word. The character introduces an escape sequence that expands to a time value or other information. escape sequences and their meanings are as follows: braces indicate optional parts.

Here is an example that outputs only seconds with an accuracy of 0, i.e. no decimal point. Read the third part of why this is important.

 TIMEFORMAT='%0R'; time sleep 1 1 

Part two

Secondly, how do we capture the output of time ? This is actually a bit complicated, this is how you make time capture from the team above

 TIMEFORMAT='%0R'; time1=$( { time sleep 1; } 2>&1 ) 

Part three

How to add time together and get the average value?

In bash, we use the $(( )) construct to do the math. Please note: bash does not support floating point, so you will do integer division (hence, precision 0.) Here is a script that will capture time from two commands and print each of the individual times and their average

 #!/bin/bash TIMEFORMAT='%0R' time1=$( { time sleep 1; } 2>&1 ) time2=$( { time sleep 4; } 2>&1 ) ave=$(( (time1 + time2) / 2)) echo "time1 is $time1 | time2 is $time2 | average is $ave" 

Output

 time1 is 1 | time2 is 4 | average is 2 

If integer division is not a starter for you, and you need precision, if you don't mind calling an external binary bc , you can do this quite easily.

 #!/bin/bash TIMEFORMAT='%3R' time1=$( { time sleep 1; } 2>&1 ) time2=$( { time sleep 4; } 2>&1 ) ave=$( bc <<<"scale=3; ($time1 + $time2)/2" ) echo "time1 is $time1 | time2 is $time2 | average is $ave" 

Output

 time1 is 1.003 | time2 is 4.003 | average is 2.503 
+6
source

In this example, I will use the preinitialized variable:

 time="54:32.96"; minutes=$(echo "$time" | cut -d":" -f1) seconds=$(echo "$time" | cut -d":" -f2 | cut -d"." -f1) millis=$(echo "$time" | cut -d":" -f2 | cut -d"." -f2) #Total time in millis totalMillisOne=$(($millis+$seconds*1000+$minutes*60000)) 

You do this with each command, and you save it in different vars, and then you do the average:

 let avMillis=$totalMillisOne+$totalMillisTwo let avMillis=$avMillis/2 

And you output it in the same input format:

 let avSeconds=$avMillis/1000 let avMillis=$avMillis-$avSeconds*1000; let avMinutes=$avSeconds/60; let avSeconds=$avSeconds-$avMinutes*60; echo "${avMinutes}:${avSeconds}.${avMillis}" 
+1
source

Source: https://habr.com/ru/post/1388387/


All Articles