home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


sed & awksed & awkSearch this book

Chapter 13. A Miscellany of Scripts

This chapter contains a miscellany of scripts contributed by Usenet users. Each program is introduced with a brief description by the program's author. Our comments are placed inside brackets [like this]. Then the full program listing is shown. If the author did not supply an example, we generate one and describe it after the listing. Finally, in Section 13.1.1, we talk briefly about the program, highlighting some interesting points. Here is a summary of the scripts:

uutot.awk
Report UUCP statistics.

phonebill
Track phone usage.

combine
Extract multipart uuencoded binaries.

mailavg
Check size of mailboxes.

adj
Adjust lines for text files.

readsource
Format program source files for troff.

gent
Get a termcap entry.

plpr
lpr preprocessor.

transpose
Perform a matrix transposition.

m1
A very simple macro processor.

13.1. uutot.awk--Report UUCP Statistics

Contributed by Roger A. Cornelius

Here's something I wrote in nawk in response to all the C versions of the same thing which were posted to alt.sources awhile back. Basically, it summarizes statistics of uucp connections (connect time, throughput, files transmitted, etc.). It only supports HDB-style log files, but will show statistics on a site-by-site, or on an overall (all sites), basis. [It also works with /usr/spool/uucp/SYSLOG.]

I use a shell wrapper which calls "awk -f" to run this, but it's not necessary. Usage information is in the header. (Sorry about the lack of comments.)

# @(#) uutot.awk - display uucp statistics - requires new awk
# @(#) Usage:awk -f uutot.awk [site ...] /usr/spool/uucp/.Admin/xferstats
# Author: Roger A. Cornelius (rac@sherpa.uucp)

#       dosome[];               # site names to work for - all if not set
#       remote[];               # array of site names
#       bytes[];                # bytes xmitted by site
#       time[];	               # time spent by site
#       files[];                # files xmitted by site
BEGIN {
	doall = 1;
	if (ARGC > 2) {
		doall = 0;
		for (i = 1; i < ARGC-1; i++) {
			dosome[ ARGV[i] ];
			ARGV[i] = "";
		}
	}

	kbyte = 1024	# 1000 if you're not picky
	bang = "!";
	sending = "->";
	xmitting = "->" "|" "<-";

	hdr1 = "Remote     K-Bytes   K-Bytes   K-Bytes " \
		"Hr:Mn:Sc Hr:Mn:Sc AvCPS AvCPS    #    #\n";
	hdr2 = "SiteName      Recv      Xmit     Total     " \
		"Recv     Xmit  Recv  Xmit Recv Xmit\n";

	hdr3 = "-------- --------- --------- --------- -------- " \
		"-------- ----- ----- ---- ----";
	fmt1 = "%-8.8s %9.3f %9.3f %9.3f %2d:%02d:%02.0f " \
		"%2d:%02d:%02.0f %5.0f %5.0f %4d %4d\n";
	fmt2 = "Totals   %9.3f %9.3f %9.3f %2d:%02d:%02.0f " \
		"%2d:%02d:%02.0f %5.0f %5.0f %4d %4d\n";
}
{
	if ($6 !~ xmitting)		# should never be
		next;
	direction = ($6 == sending ? 1 : 2)

	site = substr($1,1,index($1,bang)-1);
	if (site in dosome || doall) {
		remote[site];
		bytes[site,direction] += $7;
		time[site,direction] += $9;
		files[site,direction]++;
	}
}
END {
	print hdr1 hdr2 hdr3;
	for (k in remote) {
		rbyte += bytes[k,2];	sbyte += bytes[k,1];
		rtime += time[k,2];	stime += time[k,1];
		rfiles += files[k,2];	sfiles += files[k,1];
		printf(fmt1, k, bytes[k,2]/kbyte, bytes[k,1]/kbyte,
			(bytes[k,2]+bytes[k,1])/kbyte,
			time[k,2]/3600, (time[k,2]%3600)/60, time[k,2]%60,
			time[k,1]/3600, (time[k,1]%3600)/60, time[k,1]%60,
			bytes[k,2] && time[k,2] ? bytes[k,2]/time[k,2] : 0,
			bytes[k,1] && time[k,1] ? bytes[k,1]/time[k,1] : 0,
			files[k,2], files[k,1]);
	}

	print hdr3
	printf(fmt2, rbyte/kbyte, sbyte/kbyte, (rbyte+sbyte)/kbyte,
		rtime/3600, (rtime%3600)/60, rtime%60,
		stime/3600, (stime%3600)/60, stime%60,
		rbyte && rtime ? rbyte/rtime : 0,
		sbyte && stime ? sbyte/stime : 0,
		rfiles, sfiles);
}

A test file was generated to test Cornelius' program. Here are a few lines extracted from /usr/spool/uucp/.Admin/xferstats (because each line in this file is too long to print on a page, we have broken the line following the directional arrow for display purposes only):

isla!nuucp S (8/3-16:10:17) (C,126,25) [ttyi1j] ->
                     1131/4.880 secs, 231 bytes/sec
isla!nuucp S (8/3-16:10:20) (C,126,26) [ttyi1j] ->
                     149/0.500 secs, 298 bytes/sec

isla!sue S (8/3-16:10:49) (C,126,27) [ttyi1j] ->
                     646/25.230 secs, 25 bytes/sec
isla!sue S (8/3-16:10:52) (C,126,28) [ttyi1j] ->
                     145/0.510 secs, 284 bytes/sec
uunet!uisla M (8/3-16:15:50) (C,951,1) [cui1a] ->
                     1191/0.660 secs, 1804 bytes/sec
uunet!uisla M (8/3-16:15:53) (C,951,2) [cui1a] ->
                     148/0.080 secs, 1850 bytes/sec
uunet!uisla M (8/3-16:15:57) (C,951,3) [cui1a] ->
                     1018/0.550 secs, 1850 bytes/sec
uunet!uisla M (8/3-16:16:00) (C,951,4) [cui1a] ->
                     160/0.070 secs, 2285 bytes/sec
uunet!daemon M (8/3-16:16:06) (C,951,5) [cui1a] <-
                     552/2.740 secs, 201 bytes/sec
uunet!daemon M (8/3-16:16:09) (C,951,6) [cui1a] <-
                     102/1.390 secs, 73 bytes/sec

Note that there are 12 fields; however, the program really only uses fields 1, 6, 7, and 9. Running the program on the sample input produces the following results:

$ nawk -f uutot.awk uutot.test
Remote     K-Bytes   K-Bytes   K-Bytes Hr:Mn:Sc Hr:Mn:Sc AvCPS AvCPS    #    #
SiteName      Recv      Xmit     Total     Recv     Xmit  Recv  Xmit Recv Xmit
-------- --------- --------- --------- -------- -------- ----- ----- ---- ----
uunet        0.639     2.458     3.097  0:04:34  2:09:49     2     0    2    4
isla         0.000     2.022     2.022  0:00:00  0:13:58     0     2    0    4
-------- --------- --------- --------- -------- -------- ----- ----- ---- ----
Totals       0.639     4.480     5.119  0:04:34  2:23:47     2     1    2    8


Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.