SH: two variables in for loop

Hi, say I have a simple sh script like this:

for i in a b c d
        do
                for j in 1 2 3 4
                        do
                                echo "$i $j"
                        done
        done

and the output is

 a 1
 a 2
 a 3
 a 4
 b 1
 b 2
 b 3
 b 4
 c 1
 c 2
 c 3
 c 4
 d 1
 d 2
 d 3
 d 4

how do i make its output like this?

a 1
b 2
c 3
d 4

TIA

Don't use two loops.

n=1
for l in a b c d
do
   printf "%s %d\n" "$l" "$n"
   n=$(( $n + 1 ))
done

Thanks, I need to re-qualify my question:

what if its not a number and you can't do math on it?

e.g.
list1:

mary
eve
delilah

list2:

joseph
adam
samson

output:

mary joseph
adam eve
samson delilah
for i in `cat list1`; ... for j in `cat list2`; ... do ... print $i $j ... done

any way around this?

set -f
IFS='
'
set -- $( cat list2 )
for i in `cat list1`
do
  printf "%s %s\n" "$i" "$1"
  shift
done

amazing, thank you!

KISS principle states that design simplicity should be a key goal and unnecessary complexity avoided. :slight_smile:

paste -d ' ' list1 list2

It seems you can't have multiple "x in y" terms in a for loop, so the next best thing is probably to rewrite the loop as an index iterator:

is=(a b c d)
js=(1 2 3 4)

for ((i = 0; i < 4; i++)) 
	do echo ${is} ${js}
done

It's not as nice, but still relatively easy to read, especially if you define your lists together. :slight_smile:

That works for that specific case, but doesn't address the general problem as originally posed.

That's OK, but not POSIX compatible.

And it would be better to use the actual size of the array, not a hard-coded value:

n=0
while [ $n -lt ${#is[@]} ]
do
  printf "%s %s\n" "${is[$n]}" "${js[$n]}"
  n=$(( $n + 1 ))
done

If you want it to be POSIX compliant:

is="a b c d"
js="1 2 3 4"
set -f
while [ -n "$is" ]
do
  set -- $is; i=$1; shift; is=$*
  set -- $js; j=$1; shift; js=$*
  printf "%s %s\n" "$i" "$j"
done

I was inspired by the way cfajohnson solve up the problems. I have learn C some months ago, and like C above other languages which I needed to learn for school at that moment. But if I can use it to write scripts as well, it will be fantastic

Hi,
I am taking the inputs given to script into an array like:

array1=( `echo " $@ "` )
array2=( `echo " $@ " |tr '[a-z]' '[A-Z]'` ) 

So when I want to use values of both the above arrays in Single for loop, then what upper limit do i set for below code :

for ((i = 0; i < 4; i++))
echo ${array} ${array1}

What should be there instead of 4 ?
Cause I don't know how many arguments user will give while executing the script..it could be 2 to 10 arguments.
like :

./script.sh arg1 arg2 arg3
$#

it will give the no of parameters passed

There's no need for echo and command substitution, and it will cause the script to fail if any of the arguments contain spaces.

array1=( "$@" )

The same here. In bash 4.0 you can do:

array2=( "${@^^}" )

I repeat, "use the actual size of the array":

number_of_elements=${#array[@]}

One more, using set to array.

#!/usr/bin/ksh
set -A array1 $(cat list1)
set -A array2 $(cat list2)
n=${#array1[*]}
i=0
while (( i < n ))
do
     print "${array1[$i]} ${array2[$i]}"
    ((  i+=1  ))
done

why exactly do you a 'cat'?
Use '<' for ksh/bash.

Yes in this case this is enough. My idea was more generally example, some commands give some list and use it.

set -A array1 $(<list1)
set -A array2 $(<list2)
#cat file1
 
john
mary
adam
#cat file2
 
richard
jason
scott
#cat file3
 
steven
souchak
jay

Output :
---------

john   richard  steven
mary  jason    souchak
adam scott     jay

Please, don't hijack other people's threads - start your own.
I'd suggest rereading the rules as well.

I am not interested in any hijacking....was just need a help..

Then start a new thread (and explain the method that leads from your input to your desired output).

(And look at the paste command.)