[net.unix-wizards] Adding up columns of numbers...

mark@tove.UUCP (Mark Weiser) (03/18/85)

In article <9273@brl-tgr.ARPA> root%bostonu.csnet@csnet-relay.arpa (BostonU SysMgr) writes:
>
>P.S. One strange omission (to my knowledge) from all the UNIX tools
>is a program, similar in command syntax (groan, but probably needed)
>to 'sort' which adds up columns of numbers:
>
>	sumcol +4.6 foo
>
>Strange, must have been written hundreds of times.
>--------------------
>*End of UNIX-WIZARDS-REPLY-DIGEST-SORT-OF
>
>	-Barry Shein, Boston University

Awk is great for this.  Something like: awk '{sum += $4}\\
END {print sum}'
	-mark
-- 
Spoken: Mark Weiser 	ARPA:	mark@maryland	Phone: +1-301-454-7817
CSNet:	mark@umcp-cs 	UUCP:	{seismo,allegra}!umcp-cs!mark
USPS: Computer Science Dept., University of Maryland, College Park, MD 20742

root@trwatf.UUCP (06/10/85)

>> P.S. One strange omission (to my knowledge) from all the UNIX tools
>> is a program, similar in command syntax (groan, but probably needed)
>> to 'sort' which adds up columns of numbers:
>> 
>> 	sumcol +4.6 foo
>> 
>> Strange, must have been written hundreds of times.
>
> Awk is great for this.  Something like: awk '{sum += $4}\\
> END {print sum}'
>	-mark

Yes indeedy... here's a quick little script to get you started with
multiple columns of numbers.....


#! /bin/sh
# Total multi-column numbers....
# TRW DSG EDS SISD SDL ATF STA-Jun-10

for f in $*
	do
	echo $f | awk '{ n = 80 - ( length($0) + 2 ) ; h = (n / 2) ; \
			if ( n % 2 ) h = h-- ; \
			for ( i = 1 ; i <= h ; i++ ) printf ">" ; \
			printf " %s ",$0
			for ( i = 1 ; i <= h ; i++ ) printf "<" ; \
			printf "\n" \
			}'
	cat $f | \
	awk 'BEGIN { \
		FS = "	" ;
		for ( i = 0 ; i <= 25 ; i++ ) totals[i] = 0 \
		} \
	{ \
	if (length($0) > 0 ) { \
		print $0 ; k = 1 ; \
		for ( i = 2 ; i <= NF ; i++ ) \
			if ( length($i) > 0 ) { \
				if ( substr($i,1,1) == "$" ) \
					$i = substr($i,2,length($i) - 1)
				k++ ; totals[k] += $i ; \
				} \
		} \
	} \
	END { printf "===================" ; \
	for ( i = 2 ; i <= k ; i++ ) \
		printf "================" ; \
	printf "\n" ; \
	printf "Total expenditures\t" ; \
	for ( i = 2 ; i <= k ; i++ ) \
		printf "\t\t$%d",totals[i] ; \
	printf "\n" \
	}'
done
-- 

UUCP: ...{decvax,ihnp4,allegra}!seismo!trwatf!root	- Lord Frith
ARPA: trwatf!root@SEISMO

"Give a man a horse... and he thinks he's enormous"

root@trwatf.UUCP (Lord Frith) (06/14/85)

This could not be mailed directly....

	Subject: Need instruction for sum-column srcipt
	
	Please mail me (or post on net) the instruction on you
	column-summing shell script
	
	I tried something like  "sum-column t1" where t1 is a file
	containing 3 columns of numbers. The output is just a listing
	of t1 but without any total.

I think I know the problem.  I'll bet your file has ONLY columns of
numbers in it and know description strings in field one.  Make sure
that columns of numbers are seperated by tabs (the script uses a tab
for its FS).  Spaces are okay within the description strings.

La....

Rent				$868		$865		$865

Electricity (average)		$80		$50		$50

Phone (average)			$68		$65		$65

Gas				$80		$50		$65

Food				$680		$650		$650

If this doesn't work for you then something must have happened to the
awk script on transmission.

Something I have noticed that disturbs me is why awk seems to think
that there is an object between field seperators when that object is
null.  In other words; awk will process three consecutive tabs and say
that there are two fields whose values are null.
-- 

UUCP: ...{decvax,ihnp4,allegra}!seismo!trwatf!root	- Lord Frith
ARPA: trwatf!root@SEISMO

"Give a man a horse... and he thinks he's enormous"

ecl@mtgzz.UUCP (e.c.leeper) (06/16/85)

> Yes indeedy... here's a quick little script to get you started with
> multiple columns of numbers.....
> 
> (Followed by 35-line shell/awk script)

Far too complicated!

How about:
	echo 0 `sed -e 's/$/+/' -e 's/-+/-/' <file` pq | dc

Should handle negative numbers (e.g., "4-") also.


					Evelyn C. Leeper
					...ihnp4!mtgzz!ecl

sml@luke.UUCP (Steven List) (06/18/85)

In article <992@trwatf.UUCP> root@trwatf.UUCP (Lord Frith) writes:
>Something I have noticed that disturbs me is why awk seems to think
>that there is an object between field seperators when that object is
>null.  In other words; awk will process three consecutive tabs and say
>that there are two fields whose values are null.

Remember that they are indeed `field separators'!  Why should awk NOT
treat two consecutive separators as containing an empty field?  This is
a perfectly legitimate use.  There are times when a field is empty, and
you wouldn't want awk to treat field 3 as field 2, would you?

Take the following example, in which the third and fourth fields are
address lines:

	Smith|John|1234 Jones Street||San Francisco|CA|94111
	Brown|Jack MD|Suite 234|2345 Smith Street|San Francisco|CA|94111

Clearly, it is desirable in the first case to treat the empty field as a
field in order not to process the city as an address line (and so on).
Remember, again, that field separators are field separators, not white
space.  Sort has the same problem/feature.  Any others?

If this continues to be a problem, use something like sed to distill the
file:

	sed 's/[ \t][ \t]*/ /g' | awk ...

Then you won't have the problem/feature to contend with.  Of course, you
might run into OTHER problems.  Another option is to use the `substr'
builtin function if you have fixed format files.