jsulliva@cvbnet.UUCP (Jeff Sullivan, x4096 MS 4-2) (03/16/90)
What is the best way to provide a loop counter in a Bourne shell script? An example script is below, all it needs is the count incrementer. #!/bin/sh count=0 for i in 1 2 3 4 5 6 7 8 9 do # <increment count here> echo count=$count done I know there are other ways to accomplish the same thing, (such as the Korn shell), but I'd really like to know how to accomplish the above. Any help appreciated, -Jeff
gwyn@smoke.BRL.MIL (Doug Gwyn) (03/18/90)
i=`expr $i + 1`
jeff@quark.WV.TEK.COM (Jeff Beadles) (03/19/90)
jsulliva@cvbnet.UUCP (Jeff Sullivan, x4096 MS 4-2) writes: > What is the best way to provide a loop counter in a Bourne > shell script? An example script is below, all it needs is > the count incrementer. > #!/bin/sh > count=0 > for i in 1 2 3 4 5 6 7 8 9 > do > # <increment count here> > echo count=$count > done Well, the easiest way is to use expr. Ie: count=0 for i in 1 2 3 4 5 6 7 8 9 ; do count=`expr $count + 1` echo "Count is now $count" done Note, that if you use expr, that special shell characters must be escaped. This is bad and will cause you pain and suffering: count=`expr $count * 2` This is fine and dandy and will make you a happy camper: count=`expr $count \* 2` -Jeff -- Jeff Beadles jeff@quark.WV.TEK.COM Utek Engineering, Tektronix Inc. +1 503 685 2568 "Credo quia absurdum"
rbottin@atl.calstate.edu (Richard John Botting) (03/19/90)
Jeff <postnews@cvbnetprime.com> Asks > What is the best way to provide a loop counter in a Bourne > shell script? An example script is below, all it needs is > the count incrementer. > #!/bin/sh > count=0 [...] > # <increment count here> > echo count=$count Some people think that this answer is best thought of as a techie joke... count=`expr $count + 1` ^ ^ ^ ^ ^ The spaces a VERY significant, as are the reversed quotes. However it works and is useful in several of scripts. This is even funnier: count=` echo $count|awk '{print $1 + 1}'` I'd like to see a neat solution (other than a "increment.c" program). Dick Botting, Department of computer science, California State University, San Bernardino, CA 92407 rbottin@atl.calstate.edu >INTERNET:rbottin@atl.calstate.edu (Compuserve) paaaaar@calstate.bitnet voice:714-880-5327
brad@SSD.CSD.HARRIS.COM (Brad Appleton) (03/20/90)
In article <124@cvbnetPrime.COM> jsulliva@cvbnet.UUCP (Jeff Sullivan, x4096 MS 4-2) writes: > > What is the best way to provide a loop counter in a Bourne > shell script? An example script is below, all it needs is > the count incrementer. > > #!/bin/sh > count=0 > > for i in 1 2 3 4 5 6 7 8 9 > do > # <increment count here> > echo count=$count > done > > I know there are other ways to accomplish the same thing, > (such as the Korn shell), but I'd really like to know how > to accomplish the above. > First off, I apologize for leaving out the summary in my last post. Now ... In the Bourne shell, you can do "arithmetic" with expr. Expr can do lots of other stuff too (like pattern matching, and returning portions of strings ... read up on it! it is *very* useful). Anyway, here is an example: $ count=1 $ count=`expr $count + 1` $ echo $count 2 $ Hope this helps! PS - you may want to use a while loop instead of a for loop for your loop counting. Then again, in my experience, "while" is slower. +=-=-=-=-=-=-=-=-= "... and miles to go before I sleep." -=-=-=-=-=-=-=-=-=-+ | Brad Appleton | Harris Computer Systems Division | | | 2101 West Cypress Creek Road | | brad@ssd.csd.harris.com | Fort Lauderdale, FL 33309 USA | | ... {uunet | novavax}!hcx1!brad | MailStop 161 (305) 973-5007 | +=-=-=-=-=-=-=-=- DISCLAIMER: I said it, not my company! -=-=-=-=-=-=-=-=-=-+
merlyn@iwarp.intel.com (Randal Schwartz) (03/20/90)
In article <22788@adm.BRL.MIL>, rbottin@atl (Richard John Botting) writes: | I'd like to see a neat solution (other than a "increment.c" program). If you insist on doing the main looping in sh, for i in `perl -e '@a=1..20;print"@a";'` do echo $i done If you want to just launch stuff quickly, perl -e 'for $i (1..20) {system "echo $i";}' Look ma. No C! Just another Perl hacker, -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
tneff@bfmny0.UU.NET (Tom Neff) (03/20/90)
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@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@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@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@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
scott@SRC.Honeywell.COM (Rich Scott) (03/20/90)
In article <22788@adm.BRL.MIL> rbottin@atl.calstate.edu (Richard John Botting) writes: >Jeff <postnews@cvbnetprime.com> Asks >> What is the best way to provide a loop counter in a Bourne >> shell script? An example script is below, all it needs is >> the count incrementer. > >> #!/bin/sh >> count=0 >[...] >> # <increment count here> >> echo count=$count > ... > > [ points out significant details in using 'expr' ] > ... >I'd like to see a neat solution (other than a "increment.c" program). Well, in the Korn shell, version 11/16/88 ('ksh88') or later, you can do: for i in 1 2 3 4 5 6 7 do ((count += 1)) echo count = $count done ... which gives you much the same effect. Ksh also has the 'let' builtin, to evaluate arithmetic expresssions, and so you can do let count=count+1 instead, but the double parentheses construct is nice for short expressions, since you don't have to worry about spaces. ------------------ rich scott rich@osa.com open systems architects scott@src.honeywell.com
brad@SSD.CSD.HARRIS.COM (Brad Appleton) (03/20/90)
In article <22788@adm.BRL.MIL> rbottin@atl.calstate.edu (Richard John Botting) writes: >Jeff <postnews@cvbnetprime.com> Asks >> What is the best way to provide a loop counter in a Bourne >> shell script? An example script is below, all it needs is >> the count incrementer. > >> #!/bin/sh >> count=0 >[...] >> # <increment count here> >> echo count=$count > ... > > [ points out significant details in using 'expr' ] > ... >I'd like to see a neat solution (other than a "increment.c" program). This is the easiest one yet (using the original example): #!/bin/sh count=0 for i in 1 2 3 4 5 6 7 ; do count=$i done Has the same effect as incrementing count (and is "plainer" too). Or better yet: #!/bin/sh count=7 I guess what Im really asking is: Why did the asker of the original question need to do the incrementing if the for loop was already incrementing a variable for him? I think if we knew this we could all provide some assistance in helping him find the "nicest" way to do it. +-=-=-=-=-=-= "... and miles to go before I sleep." -=-=-=-=-=-=-=-=-+ | Brad Appleton | Harris Corporation | | brad@ssd.csd.harris.com | Computer Systems Division | | ... {uunet | novavax}!hcx1!brad | Fort Lauderdale, FL USA | +-=-=-=-=-=- DISCLAIMER: I said it, not my company! -=-=-=-=-=-=-=-=-+
pcg@odin.cs.aber.ac.uk (Piercarlo Grandi) (03/21/90)
In article <15270@bfmny0.UU.NET> tneff@bfmny0.UU.NET (Tom Neff) writes:
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:
OK. Sorry to interrupt your regularly scheduled Perl one liners :-), but
I cannot resist a plug. In the 4.2BSd contribs, there was 'jot', that
along with 'rs' and 'lam' is one of the most useful tools I have seen.
'Jot' will generate sequences of numbers, characters, strings, etc...,
with given from, to, step values.
--
Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
jik@athena.mit.edu (Jonathan I. Kamens) (03/21/90)
In all this talk about the various ways to count in a shell script, I'm surprised that no one has mentioned the "jot" program, which I believes comes standard with BSD nowadays (at least with BSD 4.3 and up -- I don't know about 4.2). The first paragraph of the description in the man page says: Jot is used to print out increasing, decreasing, random, or redundant data, usually numbers, one per line. If I wanted a loop to execute 10 times, I would just do "for i in `jot 10`; do" (or whatever the correct syntax is -- I use csh primarily, so I don't claim to know the sh syntax off the top of my head :-). Alas, it isn't freely redistributable, or at least I assume it isn't, because it isn't in the bsd-sources archives on uunet.uu.net. Somebody could probably rewrite it in perl pretty easily :-) Hell, it would even be easy to rewrite from scratch in C. Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710
mercer@ncrcce.StPaul.NCR.COM (Dan Mercer) (03/23/90)
In article <3350@hcx1.SSD.CSD.HARRIS.COM> brad@SSD.CSD.HARRIS.COM (Brad Appleton) writes: :In article <22788@adm.BRL.MIL> rbottin@atl.calstate.edu (Richard John Botting) writes: :>Jeff <postnews@cvbnetprime.com> Asks :>> What is the best way to provide a loop counter in a Bourne :>> shell script? An example script is below, all it needs is :>> the count incrementer. :> :>> #!/bin/sh :>> count=0 :>[...] :>> # <increment count here> :>> echo count=$count :> ... :> :> [ points out significant details in using 'expr' ] :> ... :>I'd like to see a neat solution (other than a "increment.c" program). : : :This is the easiest one yet (using the original example): : : #!/bin/sh : count=0 : for i in 1 2 3 4 5 6 7 ; do : count=$i : done : :Has the same effect as incrementing count (and is "plainer" too). :Or better yet: : : #!/bin/sh : count=7 : :I guess what Im really asking is: : :Why did the asker of the original question need to do the :incrementing if the for loop was already incrementing a variable :for him? I think if we knew this we could all provide some assistance :in helping him find the "nicest" way to do it. : :+-=-=-=-=-=-= "... and miles to go before I sleep." -=-=-=-=-=-=-=-=-+ :| Brad Appleton | Harris Corporation | :| brad@ssd.csd.harris.com | Computer Systems Division | :| ... {uunet | novavax}!hcx1!brad | Fort Lauderdale, FL USA | :+-=-=-=-=-=- DISCLAIMER: I said it, not my company! -=-=-=-=-=-=-=-=-+ How prevalent is the BC desk calculator? We had need not only for simple addition, but for more complicated arithmetic and even hexadecimal computation. At first, I just piped the calculations to BC (which itself is just a front end to DC) and read the response. However, this proved to be quite costly in terms of cpu time. Then I got a great idea, starting BC in background and hooking its input and output to named pipes. Then, by sending computations to one FIFO by echo and reading the response (with either read or line), I'm able to do quite complicated computations with low overhead. Oddly enough, even for simple loop counting, it can completely blow the pants off an x=`expr ...` solution. -- Dan Mercer Reply-To: mercer@ncrcce.StPaul.NCR.COM (Dan Mercer)