|
For the almighty of adding columns
#######################################################################
## add_up_columns
## utility that takes input and whenever Number-of-fields (NF)
## is greater than 0, it adds up by column. Totals line is
## formatted identically to the last data line.
#######################################################################
tr "%" " " |\
awk 'BEGIN { limit = 1e-8 }
{ ### if this is a data line, sum the columns ###
if (NF > 0)
{ if (NF > maxNF) { maxNF = NF }
if (length($0) > maxlen) { maxlen = length($0) }
for (f = 1; f <= NF; f++)
{ sum[f] += $f
if ($f+0.0 != 0) numeric_line = 1
if ($f+0.0 != 0) { ftype[f] = "f" } else { ftype[f] = "s" }
}
if (numeric_line) { observations += 1; numeric_line = 0 }
numflds = split($0,fieldarr," ")
print $0
tempstr=$0
got_data = 1
}
### if this line has no fields, then print column totals ###
if (NF == 0 && got_data)
{ ### if all totals are zero then don`t print cause its prob. a title ###
valid_total = 0
for (f = 1; f <= maxNF; f++) { if (sum[f] != 0) valid_total = 1 }
if (!valid_total)
{ printf "\n" }
else
{ ### get starting location of each field in last data line ###
lastchar = " "; fld = 0
for (c = 1; c <= length(tempstr); c++)
{ char = substr(tempstr,c,1)
if (char != " " && lastchar == " ") { fld +=1; fldpos[fld] = c-1 }
lastchar = char
}
### get remaining format data from last data line ###
for (f = 1; f <= numflds; f++)
{ fs = f ""
fdata = fieldarr[fs]
fldlen[f] = length(fdata)
if (ftype[f] == "s")
{ digit[f] = ""; period = "" }
else
{ period = "."
if (index(fdata,".") != 0) { digit[f] = fldlen[f]-index(fdata,".") } else { digit[f] = 0 }
}
pad[f] = fldpos[f] - fldpos[f-1] + fldlen[f-1] - 1
format[f] = "%" (fldlen[f] + fldpos[f] - fldpos[f-1] - fldlen[f-1]) period digit[f] ftype[f]
}
### print dotted line and totals row ###
for (i = 1; i <= maxlen; i++) { printf "-" }
printf "\n"
for (f = 1; f <= maxNF; f++) { avg[f] = sum[f]/observations }
if (sum[1]+0.0 == 0) { sum[1] = "TOT"; avg[1] = "AVG" }
for (f = 1; f <= maxNF; f++) { printf format[f],sum[f] }
printf "\n"
for (f = 1; f <= maxNF; f++)
{ printf format[f],avg[f]
format[f] = ""; sum[f] = 0; avg[f] = 0
}
printf "\n"; printf "\n"; printf "\n"
}
observations = 0
maxNF = 0
maxlen = 0
got_data = 0
}
}
END { ### if last total has not been printed, then print it now ###
if (got_data)
{ ### get starting location of each field in last data line ###
lastchar = " "; fld = 0
for (c = 1; c <= length(tempstr); c++)
{ char = substr(tempstr,c,1)
if (char != " " && lastchar == " ") { fld +=1; fldpos[fld] = c-1 }
lastchar = char
}
### get remaining format data from last data line ###
for (f = 1; f <= numflds; f++)
{ fs = f ""
fdata = fieldarr[fs]
fldlen[f] = length(fdata)
if (ftype[f] == "s")
{ digit[f] = ""; period = "" }
else
{ period = "."
if (index(fdata,".") != 0) { digit[f] = fldlen[f]-index(fdata,".") } else { digit[f] = 0 }
}
pad[f] = fldpos[f] - fldpos[f-1] + fldlen[f-1] - 1
format[f] = "%" (fldlen[f] + fldpos[f] - fldpos[f-1] - fldlen[f-1]) period digit[f] ftype[f]
}
### print the totals row ###
for (i = 1; i <= maxlen; i++) { printf "-" }
printf "\n"
for (f = 1; f <= maxNF; f++) { avg[f] = sum[f]/observations }
if (sum[1]+0.0 == 0) { sum[1] = "TOT"; avg[1] = "AVG" }
for (f = 1; f <= maxNF; f++) { printf format[f],sum[f] }
printf "\n"
for (f = 1; f <= maxNF; f++) { printf format[f],avg[f] }
printf "\n"
}
}'
|