[opensuse] bash - how to dereference loop counter $i to something like ${$i} ??
![](https://seccdn.libravatar.org/avatar/27aacf61a13c66fcc083fcf8a84823bc.jpg?s=120&d=mm&r=g)
Listmates, I don't know if this can be done, but I was trying to get a c style for loop to dereference the counter i to the equivalent command line parameter $1, $2, etc.. Like: for ((i=1;i<=$#;i++)); do echo "\$$i = ${$i} done but obviously that just results in a bad substitution. I've been through man bash with parameter substitution, but I still can't find a way to do it. I know how to do it with a counter and "for i in "$@"", but I was trying to see if I could do it with a pure dereference. Any way? -- David C. Rankin, J.D., P.E. Rankin Law Firm, PLLC 510 Ochiltree Street Nacogdoches, Texas 75961 Telephone: (936) 715-9333 Facsimile: (936) 715-9339 www.rankinlawfirm.com -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/b12cfb65ca4faebc3e3aac17838e8f8d.jpg?s=120&d=mm&r=g)
On Saturday 23 August 2008 17:24, David C. Rankin wrote:
Listmates,
I don't know if this can be done, but I was trying to get a c style for loop to dereference the counter i to the equivalent command line parameter $1, $2, etc.. Like:
for ((i=1;i<=$#;i++)); do echo "\$$i = ${$i} done
Look into the "let" and "eval" built-ins (in the BASH manual page). Understanding BASH array variables may also help.
...
-- David C. Rankin
Randall Schulz -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/ee738d4e31faf58ee5b06d27af86a6f9.jpg?s=120&d=mm&r=g)
Hello, On Sat, 23 Aug 2008, Randall R Schulz wrote:
On Saturday 23 August 2008 17:24, David C. Rankin wrote:
Listmates,
I don't know if this can be done, but I was trying to get a c style for loop to dereference the counter i to the equivalent command line parameter $1, $2, etc.. Like:
for ((i=1;i<=$#;i++)); do echo "\$$i = ${$i} done
First of all, this can be done more easily as: i=1 for arg; do echo "$i: $arg"; i=$[i+1]; done or i=1; for arg; do echo "$i: $arg"; i=$((i+1)); done; the $i is only there for numbering the output.
Look into the "let" and "eval" built-ins (in the BASH manual page). Understanding BASH array variables may also help.
You should avoid eval if at all possible. Think: "eval is evil" ;) There's also ${!i}: i=1; while test $i -le $#; do echo "$i: ${!i}"; ((i+=1)); done My bash is too old for the 'for (( ... )); do ...' syntax. Nothing wrong using it, as long as you're aware that it's not portable, not even to slightly dusted bashes. And note that I use three "internal" ways to manipulate $i (without using the 'for (( .. ))' syntax). Putting the above into functions foo1 .. foo3 yields: $ for i in 1 2 3; do `eval echo "foo${i}"` a "b c" d | xargs echo; done 1: a 2: b c 3: d 1: a 2: b c 3: d 1: a 2: b c 3: d Please use 'set -x' to look at what's happening when. And compare to: $ for i in 1 2 3; do eval `echo "foo${i}"` a "b c" d | xargs echo; done And no, it doesn't seem to work with 'do foo${!i} a "b c" d'. And for other ways, you need to escape/quote the arguments to fooN, e.g.: $ for i in 1 2 3; do eval "foo${i}" 'a "b c" d' | xargs echo; done Have fun analyzing & HTH, -dnh --
The three "R"s of Microsoft support: Retry, Reboot, Reinstall You forgot one: Repeat -- Mark Atwood, Lars Balker Rasmussen -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/8434092a3798a0467c3f2371ef030fc6.jpg?s=120&d=mm&r=g)
----- Original Message -----
From: "David C. Rankin"
Listmates,
I don't know if this can be done, but I was trying to get a c style for loop to dereference the counter i to the equivalent command line parameter $1, $2, etc.. Like:
for ((i=1;i<=$#;i++)); do echo "\$$i = ${$i} done
but obviously that just results in a bad substitution. I've been through man bash with parameter substitution, but I still can't find a way to do it. I know how to do it with a counter and "for i in "$@"", but I was trying to see if I could do it with a pure dereference. Any way?
for ((i=1;i<=$#;i++)); do echo "\$$i = ${$i} done
# load up a fake command line set aa bb cc dd "ee has spaces" ff gg n=0 for i in "$@" ;do ARGV[$n]=$i echo "\$$n = \"$i\"" ((++n)) done after this, you have an array ARGV[] that you can reference via variable in the subscript n=2 echo "ARGV[$n] = \"${ARGV[$n]}\"" To more closely follow your example, and to more clearly show what you wanted, another example * uses the c-like syntax where possible * uses the array instead of $@ to generate the display set aa bb cc dd "ee has spaces" ff gg n=1 ;for i in "$@" ;do ARGV[$n]=$i ;((++n)) ;done for ((n=1;$n<=${#ARGV[@]};++n)) ;do echo "\$$n = \"${ARGV[$n]}\"" done In ksh it's a little handier, since you can create & populate an array in one shot: * the $0 is just a placeholder so we can count from 1 later like the other examples * the < vs <= is not a typo set -A ARGV "$0" "$@" for ((n=1;$n<${#ARGV[@]};++n)) ;do echo "\$$n = \"${ARGV[$n]}\"" done In zsh it's even simpler yet, since it has a built-in argv[]: for ((n=1;$n<=${#argv[@]};++n)) ;do echo "\$$n = \"${argv[$n]}\"" done All of them produce the same: $1 = "aa" $2 = "bb" $3 = "cc" $4 = "dd" $5 = "ee has spaces" $6 = "ff" $7 = "gg" note: when I say ksh I mean ksh. Not pdksh, not the symlink to bash that bash installs by default, not the symlink to zsh that zsh installs by default. Symlinks like that are plain broken as far as I'm concerned unless the respective shells actually impliment all of ksh's features and behaviors, including performance oriented otherwise invisible fetures. (like, is the sleep built-in?) All of the examples could have used $# in place of ${#array[@]} But, Since the business end of the loop is going to use the array for the actual work, then the iterator should refer to the same actual data if possible, not some other data that just happens to / should usually be the same. Anything else is just sloppy programming / sloppy logic. -- Brian K. White brian@aljex.com http://www.myspace.com/KEYofR +++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++. filePro BBx Linux SCO FreeBSD #callahans Satriani Filk! -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
![](https://seccdn.libravatar.org/avatar/27aacf61a13c66fcc083fcf8a84823bc.jpg?s=120&d=mm&r=g)
Brain, Ken, David: Thanks. I can now skin that cat 4 different ways ;-) -- David C. Rankin, J.D., P.E. Rankin Law Firm, PLLC 510 Ochiltree Street Nacogdoches, Texas 75961 Telephone: (936) 715-9333 Facsimile: (936) 715-9339 www.rankinlawfirm.com -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
participants (4)
-
Brian K. White
-
David C. Rankin
-
David Haller
-
Randall R Schulz