Reputation: 13
Im trying to calculate the average of a list of hours, I found an awk command that works pretty well but i want to know how is works.
This is my list of hours:
20:09 19:24 19:28
And this is the program
awk -F':' '
BEGIN {
total=0;
}
{
total+=(($1*3600)+($2*60)+$3);
}
END {
a=(total/NR);
printf "%02d:%02d:%02d\n",(a/3600),((a/60)%60),(a%60)
}' file
I understand the first part and how it convert everything into seconds but nothing more.
Upvotes: 0
Views: 71
Reputation: 26581
Short answer: this code computes the average duration of some timing which is located in file
file
I assume you have a file which looks something like:
00:02:30: something1
00:01:14: something2
01:02:04: something3
I also assume that the first three values represent a duration in hours minutes and seconds.
What the code does is per line extract the duration and convert it into total seconds and adds it to a value total
. When all lines are processed, it computes the average duration by dividing it by NR
which represents the total number of lines processed. It then prints the average value out by converting it back into hh:mm:ss
note: the code can be reduced into
awk -F':' '{t+=3600*$1 + $2*60 + $3}
END{t/=NR; printf "%02d:%02d:%02d\n",t/3600,(t/60)%60),(t%60) }' file
Upvotes: 0
Reputation: 133770
Could you please try following explanation, based on OP's shown attempts.
# Start awk program from here, set field separator as :
awk -F':' '
# The BEGIN block is only executed once, when the script starts
BEGIN{
# Initialize total
total=0
}
# Main script executes for each input line
{
# Convert to seconds: Multiply first field $1 by 3600 and second by 60
# then add the terms together, and add to total
total+=(($1*3600)+($2*60)+$3)
}
# The END block executes when we have finished reading all lines
END{
# Calculate average: divide total by number of lines
a=(total/NR)
# Print result, where a/3600 is hours,
# (a/60)%60 is remainder in minutes, a%60 remainder seconds
# -- the %02d format specifier takes care to discard any decimals
printf "%02d:%02d:%02d\n",(a/3600),((a/60)%60),(a%60)
}
' file # input file name
Upvotes: 4