: ' : Use awk to sum column indicated from standard input. Values in that : column may be numeric or #:# or #:#:#. Output format will attempt to : match the input format by adapting to the maximum number of : separated values : The -f flag can be used to force the output format to 1, 2, or 3. : The -v flag emits each input line followed by a running sum. : The -i flag prepends a leading tab to the -v output. : The -a # flag computes an array of partial sums of lines identical in col # : The -d flag computes deltas (from line to line) instead of sums : The -y flag allows yymmdd@hh:mm:ss input (by ignoring the yymmdd@) : : Usage: sumx [-f #] [-a #] [-d] [-y] [-v [-i]] [[-]] : : Corey Satten, corey @ cac.washington.edu : http://staff.washington.edu/corey : ' for i in $*; do case "$1" in -f) Fval=$2; shift;; # force output format -d) dflag=1; vflag=1;; # emit deltas (implies -v) -v) vflag=1;; # emit running sum -vi) vflag=1; iflag=1;; # emit running sum with leading tab -iv) vflag=1; iflag=1;; # emit running sum with leading tab -i) iflag=1;; # emit leading tab in -v output -y) yflag=1;; # strip yymmdd@ from time field -a) Acol="$2"; shift;; # compute array of partial sums *) break;; esac shift done case "$1" in "") fld=1;; # default is column 1 -*) fld="-($1)"; shift;; # forgive negative column numbers *) fld="$1"; shift;; # use column expression specified esac case "$Acol" in # modifications for array of partial sums '') UM=sum; UE="sum"; FMT='""'; LOOP=;; *) UM="sumv[\$($Acol)]"; UE="sumv[s]"; FMT='s "\t"'; LOOP="for (s in sumv)";; esac exec mawk " BEGIN{OFMT=\"%f\"; timefmt = ${Fval-"-4"}+4} { if (\$($fld) ~ /:/) { # do simple case for speed only sign = 1; if ((n=split(\$($fld),a,\":\")) > 1 && n > timefmt) timefmt = n v=a[1] ${yflag+sub(/^......@/,\"\",v)} if (v ~ /\+/) { # days+hours i=index(v, \"+\") v = substr(v,1,i-1) * 24 + substr(v,i+1) } if (v < 0) { v = -v; sign = -1; } for (i=2; i<=n; ++i) { v = v * 60 + a[i] } $UM += sign*v } else $UM += \$($fld) # speed optimization only ${vflag+ ${dflag+$UM -= last} # delta mode printf(\"${iflag+\t}%s\t\", \$0) if (timefmt % 4 == 3) # H:MM:SS format printf(\"%d:%02d:%07.4f\\n\",$UM/3600,($UM%3600)/60,$UM%60) else if (timefmt % 4 == 2) # H:MM format printf(\"%d:%07.4f\\n\",$UM/60,$UM%60) else # single numeric format print $UM ${dflag+last = $UM+last; $UM=0}} } END { $LOOP { if (timefmt % 4 == 3) # H:MM:SS format printf(\"%s%d:%02d:%07.4f\\n\", $FMT, $UE/3600,($UE%3600)/60,$UE%60) else if (timefmt % 4 == 2) # H:MM format printf(\"%s%d:%07.4f\\n\", $FMT, $UE/60,$UE%60) else # single numeric format print $FMT $UE } } " ${1+"$@"} #old, simple, non-time version, keep for reference #exec /bin/awk "{sum+=\$($fld)} END {print sum}" ${1+"$@"};;