0

I have two variables

VAR1="1 2 3"
VAR2="Bob Tom Kate"

I want to echo something like this but I don't know how to use multiple variables in a loop:

1 for Bob
2 for Tom
3 for Kate

All I can is:

(
for i in $VAR1; do 
echo "$i"
done
)
Kusalananda
  • 333,661
trilisser
  • 103

3 Answers3

2

In zsh:

var1=(1 2 3)
var2=(Bob Tom Kate)
for i j in ${var1:^var2}; do
  printf '%q, %q\n' $i $j
done

If those variables may contain empty values:

var1=('' 2 3)
var2=('Bob XIV' Tom '')
for i j in "${(@)var1:^var2}"; do
  printf '%q, %q\n' "$i" "$j"
done

(or "${var1[@]:^var2}", the point being to get a similar behaviour as with the "$@" parameter expansion of the Bourne shell, or the "${array[@]}" of the Korn shell where elements are passed separate and verbatim as if quoted including empty ones)

${a:^b} is an array zipping parameter expansion operator. There's also the ${a:^^b} variant which reuses elements of the shorter array if the arrays don't have the same number of elements.

In zsh, best is to avoid dereferencing array elements via their index if possible as that is very inefficient in current versions especially for large arrays, mainly because of the fact zsh doesn't record the size of its arrays, so even though accessing the nth element should be instantaneous as that's indexing in a C array, zsh still needs to check n is not past the end of the arrays for which it still needs to check the n - 1 elements before it.

For looping over 3 or more arrays, you still need to do that though:

n=$#var1
for (( i = 1; i <= n; i++ ))
  printf '%q, %q, %q\n' "$var1[i]" "$var2[i]" "$var3[i]"

Which would be orders of magnitudes slower than the equivalent code in ksh93 or even bash.

n=${#var1[@]}
for (( i = 0; i < n; i++ )) {
  printf '%q, %q, %q\n' "${var1[i]}" "${var2[i]}" "${var3[i]}"
}
1

In bash

$ function assoc() { for i in $VAR1; do echo "$i for $1" ; shift; done ; }
$ assoc $VAR2
1 for Bob
2 for Tom
3 for Kate
stevea
  • 431
0

Transform you variables into arrays and work with them.

#!/bin/bash

VAR1="1 2 3" VAR2="Bob Tom Kate"

since you have spaces in the original string, then a simple paranthesis will work

arr1=($VAR1) arr2=($VAR2)

for (( i=0; i<${#arr1[@]}; i++ )) do echo ${arr1[$i]} for ${arr2[$i]} done

This assumes that both your original variables have same number of elements.

If your variables would have a different way of splitting words (commas for example), then you would have to use a different method of splitting string into array.

White Owl
  • 5,129