: '
: 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+"$@"};;