Bourne Shell (/bin/sh) counting?
Tom Neff
tneff at bfmny0.UU.NET
Tue Mar 20 05:17:54 AEST 1990
Despite all the neat Perl ways to do it, I consider the little
'count' program an important tool for shell programmers. You
generally just say
for i in `count 1 100`
or whatever. Here it is again:
---- cut here --------------------------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# Makefile
# README
# count.1
# count.c
# This archive created: Mon Mar 19 14:15:56 1990
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'Makefile'
then
echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X#
X# Makefile for count. This is a little overkill, but what the heck.
X# (This is public domain too!)
X# Written by: Jeff Beadles
X# jeff at quark.WV.TEK.COM ...tektronix!quark.wv!jeff
X#
X
XCC = cc
XCFLAGS =
X
X#For the executable file
XBINDIR=/usr/bin
X
Xcount: count.c Makefile
X $(CC) $(CFLAGS) count.c -o count
X
Xinstall: count
X -strip count
X cp count ${BINDIR}/count
X chmod 755 ${BINDIR}/count
X
X rm -f *.o core a.out
X
Xclobber: clean
X rm -f count
X
SHAR_EOF
fi
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
X count - By: Jeff Beadles jeff at quark.WV.TEK.COM
X
X
X This program will count from the starting number to the stop
X number, using the character 'fs' as the field seperator.
X
X Note, that fs may be in several forms:
X -A will use the letter 'A'
X -- will use a '-' as fs, and
X -\011 will use a tab (Octal 011) as the fs. (sh does the expansion.)
X
X Bugs may be sent to me if desired.
X Please keep your flames to yourself. What do you expect for free?
SHAR_EOF
fi
if test -f 'count.1'
then
echo shar: "will not over-write existing file 'count.1'"
else
sed 's/^X//' << \SHAR_EOF > 'count.1'
X.\"
X.\" @(#)count 1.0 05/09/89
X.\"
X.TH COUNT 1 "09 MAY 1989"
X.UC 4
X.SH NAME
Xcount \- count numbers from a start to a stop point.
X.SH SYNOPSIS
X.B count [-c] start stop
X.SH DESCRIPTION
X.I Count
Xwill count thru an integer sequence of numbers from
X.I Start
Xto
X.I Stop
Xwith a newline after each number.
X
XOptionally,
X.I -c
Xmay be on the command line. This may be in one of two forms.
X.I -$
Xwill put a
X.I $
Xbetween each number.
X.I -040
Xwill put a space (Octal
X.I 040
X) between each number.
X
X.SH AUTHOR
XJeff Beadles jeff at quark.WV.TEK.COM
SHAR_EOF
fi
if test -f 'count.c'
then
echo shar: "will not over-write existing file 'count.c'"
else
sed 's/^X//' << \SHAR_EOF > 'count.c'
X/* Count.c Released into the public domain on 05/09/89
X * Written by: Jeff Beadles jeff at quark.WV.TEK.COM
X * or ...!tektronix!quark.WV!jeff
X *
X * NOTE: This program is not supported by Tektronix, Inc.
X *
X * This program will count from the starting number to the stop
X * number, using the character 'fs' as the field seperator.
X * Note, that fs may be in several forms:
X * -A will use the letter 'A'
X * -- will use a '-' as fs, and
X * -\011 will use a tab (Octal 011) as the fs. (sh does the expansion.)
X *
X * Bugs may be sent to me if desired.
X * Please keep your flames to yourself. What do you expect for free?
X *
X */
X
X
X#include <stdio.h>
X#include <ctype.h>
X
X/*
X * Default field seperator
X */
X
X#ifndef FS
X#define FS '\n'
X#endif
X
Xint
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X
X{
X void usage();
X int oatc();
X int start = 0; /* Start count */
X int stop = 0; /* Stop count */
X int pos = 1; /* Position in command line for parsing */
X char fs = FS; /* Field Separator */
X
X if ( argc < 2)
X usage(argv[0]); /* Does not return */
X
X if ( argv[1][0] == '-' ) {
X if ( (isdigit(argv[1][1])) && (strlen(argv[1]) == 4) )
X fs=oatc(argv[1] + 1);
X else
X fs = argv[1][1];
X pos++; /* On to the next arg... */
X }
X start = atoi(argv[pos++]); /* Start here, and... */
X
X if ( argc <= pos)
X usage(argv[0]); /* Does not return */
X
X stop = atoi(argv[pos]); /* Stop here. */
X if ( start >= stop) /* Are they brain damaged? */
X {
X fprintf(stderr,"Error: START must be less than STOP\n");
X exit(-2);
X }
X
X/*
X Yes, this is it. It even prints a '\n' when done, if the fs != '\n' (Wow)
X */
X while ( start <= stop )
X printf("%d%c",start++,( (start != stop) ? fs : '\n' ) );
X}
X
X/*
X Can you figure out this function with no comments? Sure, you can.
X*/
Xvoid usage(program)
Xchar *program;
X
X{
X fprintf(stderr,"Usage: %s [ -c] start stop\n",program);
X exit(-1);
X}
X
X/*
X * octal ascii to char
X */
X
Xint oatc(str)
Xchar *str;
X {
X int retval=0;
X int pos=0;
X int tmp=0;
X int loop;
X static int table[] = { 1, 8, 64 }; /* Powers of 8, to avoid POW */
X
X
X for(loop=strlen(str) - 1; loop >= 0; loop--)
X retval += ( (str[loop] - '0') * table[pos++] );
X
X return((char)retval);
X}
X
SHAR_EOF
fi
exit 0
# End of shell archive
More information about the Comp.unix.questions
mailing list