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?
marcpascual:
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
KISS principle states that design simplicity should be a key goal and unnecessary complexity avoided.
paste -d ' ' list1 list2
Exolon
August 1, 2008, 5:12pm
7
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.
That works for that specific case, but doesn't address the general problem as originally posed.
exolon:
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.
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
westhar
October 18, 2008, 2:20pm
10
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=( "${@^^}" )
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[i]} ${array1[i]}
What should be there instead of 4 ?
Cause I dont know how many arguments user will give while executing the script..it could be 2 to 10 arguments.
like : ./script.sh arg1 arg2 arg3
I repeat, "use the actual size of the array":
number_of_elements=${#array[@]}
kshji
June 30, 2009, 10:37am
14
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
kshji:
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.
kshji
June 30, 2009, 11:14am
16
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
pankajpw:
#cat file1
<snip-snap>
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.)