afc@shibaya.lonestar.org (Augustine Cano) (01/27/91)
I am trying to specify (at run time) an upper limit for a loop in a shell script. In pseudo-code the ideal would be something like this: read i for 0 to i do ... done The closest I've come to this is what follows: echo "enter upper limit" read limit for i in 0 1 2 3 4 5 6 7 8 9 do # some processing that involves $i goes here if test $i -ge $limit-1 ; then # NOTE: for i=3, I want iterations 0,1,2 break fi done Not very elegant since a limit of 10 iterations is hard-wired. Can anybody think of a more concise way to do this? Using PERL is not an option, this must be portable sh code. The next problem is the thorny one. Some shell variables having been previously set up, say: var0=REAL_VALUE0 var1=REAL_VALUE1 var2=REAL_VALUE2 var3=REAL_VALUE3 var4=REAL_VALUE4 I want to manipulate variable names inside the above loop such that I could display the "REAL VALUEx" based on the current value of $i. At the prompt, with the above variables initialized, echo $var0, echo $var1, etc... yield the expected results. When I put echo $var$i in the loop, it doesn't work. Other variations, such as echo $"$var$i", etc... don't work either. How can this be done? How is it possible to make sh group $var and $i first and then get the real value of the variable that results from combining the 2 strings? Any help will be greatly appreciated!!! I'll summarize e-mail responses. Thanks in advance. -- Augustine Cano INTERNET: afc@shibaya.lonestar.org UUCP: ...!{ernest,egsner}!shibaya!afc
]) (01/28/91)
In article <1991Jan27.044258.18779@shibaya.lonestar.org> afc@shibaya.lonestar.org (Augustine Cano) writes: >I am trying to specify (at run time) an upper limit for a loop in a shell >script. In pseudo-code the ideal would be something like this: > >read i >for 0 to i >do >... >done Let me give you the ksh version first, then the (slower) sh mods -- it's slower because each iteration requires a fork/exec not required in ksh. : # ksh version # (note -- in commentary, Augustine requests that we stop at i-1) typeset -i i j # make things run faster by naming these as ints j=0 # could be done on the typeset, but needed for the sh version echo "enter limit: \c" read i dummy # in case we get two words; also, you should test for a bad $i while [ $j -lt $i ] do eval 'var'$j'="$REAL_VALUE'$j'"' eval 'echo "var$j is $var'$j'"' ((j = $j + 1)) done exit The sh version is the same except for two parts: delete the typeset, because it's not in sh, and replace ((j = $j + 1)) with a call j=`expr $j + 1` (which is the extra fork/exec). >Not very elegant since a limit of 10 iterations is hard-wired. Can anybody >think of a more concise way to do this? Using PERL is not an option, this >must be portable sh code. > >The next problem is the thorny one. Some shell variables having been >previously set up, say: > >var0=REAL_VALUE0 >var1=REAL_VALUE1 >var2=REAL_VALUE2 >var3=REAL_VALUE3 >var4=REAL_VALUE4 > >I want to manipulate variable names inside the above loop such that >I could display the "REAL VALUEx" based on the current value of $i. Assuming that all possible REAL_VALUE* variables were defined somehow, the two eval instructions inthe sample loop will store their contents in the variables var0 through var${i-1} and print them out. If you're a Rexx programmer, eval in the shell is like Rexx's interpret. The args to eval are evaluated once (losing one level of quotation), the 'eval ' is stripped, and the resulting string is evaluated and executed. ...Kris -- Kristopher Stephens, | (408-746-6047) | krs@uts.amdahl.com | KC6DFS Amdahl Corporation | | | [The opinions expressed above are mine, solely, and do not ] [necessarily reflect the opinions or policies of Amdahl Corp. ]
mcgrew@ichthous.Eng.Sun.COM (Darin McGrew) (01/29/91)
afc@shibaya.lonestar.org (Augustine Cano) writes: >I am trying to specify (at run time) an upper limit for a loop in a shell >script. In pseudo-code the ideal would be something like this: > >read i >for 0 to i >do >... >done I'd use a while loop, as such: read max # Note: there is no sanity check of $max counter=0 while [ $counter -le $max ] do ... counter=`expr $counter + 1` done >The next problem is the thorny one. Some shell variables having been >previously set up, say: > >var0=REAL_VALUE0 >var1=REAL_VALUE1 >var2=REAL_VALUE2 >var3=REAL_VALUE3 >var4=REAL_VALUE4 > >I want to manipulate variable names inside the above loop such that >I could display the "REAL VALUEx" based on the current value of $i. You need to use the eval operator. The first evaluation will get the value of $i, and the second one (ie, the one caused by the eval operator) will use that value as part of the for loop: eval echo \$var$i Darin McGrew "The Beginning will make all things new, mcgrew@Eng.Sun.COM New life belongs to Him. Affiliation stated for He hands us each new moment saying, identification purposes only. 'My child, begin again.... You're free to start again.'"
maart@cs.vu.nl (Maarten Litmaath) (01/29/91)
In article <a21801wv11X.00@amdahl.uts.amdahl.com>, krs@uts.amdahl.com (Kris Stephens [Hail Eris!]) writes: )In article <1991Jan27.044258.18779@shibaya.lonestar.org> ) afc@shibaya.lonestar.org (Augustine Cano) writes: )>I am trying to specify (at run time) an upper limit for a loop in a shell )>script. In pseudo-code the ideal would be something like this: )> )>read i )>for 0 to i )>do )>... )>done ) )Let me give you the ksh version first, then the (slower) sh mods -- it's )slower because each iteration requires a fork/exec not required in ksh. Not necessarily. read i t0= rest='1 2 3 4 5 6 7 8 9' for h in '' $rest do for t in "$t0" $rest do for u in 0 $rest do case $h$t$u in 999) echo overflow >&2 exit 1 ;; $i) break 3 esac do_something done done t0=0 done This example works for 999 iterations. Enough? -- kinnersley@kuhub.cc.ukans.edu (Bill Kinnersley): "Do phonograph turntables turn the other way in Australia?" gjh@krebs.acc.Virginia.EDU (Galen J. Hekhuis): "How do you think satanic messages were discovered on records?"
bob@wyse.wyse.com (Bob McGowen x4312 dept208) (02/02/91)
In article <a21801wv11X.00@amdahl.uts.amdahl.com> krs@amdahl.uts.amdahl.com (Kris Stephens [Hail Eris!]) writes: >In article <1991Jan27.044258.18779@shibaya.lonestar.org> afc@shibaya.lonestar.org (Augustine Cano) writes: >>I am trying to specify (at run time) an upper limit for a loop in a shell >>script. In pseudo-code the ideal would be something like this: >> >>read i >>for 0 to i >>do >>... >>done deleted ksh stuff >The sh version is the same except for two parts: delete the typeset, >because it's not in sh, and replace ((j = $j + 1)) with a call >j=`expr $j + 1` (which is the extra fork/exec). > >>Not very elegant since a limit of 10 iterations is hard-wired. Can anybody >>think of a more concise way to do this? Using PERL is not an option, this >>must be portable sh code. deleted second problem Another solution, involving only one extra fork/exec, is a small C program to take a command line arg which is the number of iterations needed and which prints out a character that number of times. This would be used in a for loop arg list with backquotes: for count in `iter $1` do process for $1 iterations done I wrote this once but do not have the code to hand, so the following is from memory and includes no error checking: #include <stdio.h> main(argc,argv) int argc; char **argv; { int count, iterations; iterations=atoi(*(argv+1)); for(count=0; count < iterations; count++) { putchar('a'); putchar(' '); /* to separate the characters */ } } A slightly more complex version was written up in UNIXWorld, Wizard's Grabbag. Instead of putting out one character per iteration it printed the integer with printf, followed by a newline. I do not remember the rationale given for using this method. The mods are left up to you if you prefer that approach. I did just compile the above and it works as advertised. Note that the for loop variable will not contain anything of value, it is just a method for looping a specific number of times. Bob McGowan (standard disclaimer, these are my own ...) Product Support, Wyse Technology, San Jose, CA ..!uunet!wyse!bob bob@wyse.com