Reputation: 635
I have two arrays that I want to loop in. I construct those properly and before going into for loop, I do echo them to be sure everything is ok with arrays. But when I run the script, it outputs an error:
l<=: syntax error: operand expected (error token is "<="
I consulted the mighty Google and I understood it suffers from the lack of the second variable, but I mentioned earlier I do echo the values and everything seems to be OK. Here is the snippet..
#!/bin/bash
k=0
#this loop is just for being sure array is loaded
while [[ $k -le ${#hitEnd[@]} ]]
do
echo "hitEnd is: ${hitEnd[k]} and hitStart is: ${hitStart[k]}"
# here outputs the values correct
k=$((k+1))
done
k=0
for ((l=${hitStart[k]};l<=${hitEnd[k]};l++)) ; do //this is error line..
let array[l]++
k=$((k+1))
done
The variables in the for loop are echoed correctly but for loop won't work.. where am I wrong?
#as gniourf_gniourf answered:
"... At some point, k will reach the value ${#hitEnd[@]}, and this is exactly when hitEnd[k] is not defined and expands to an empty string! Bang!"
meaning error output is displayed not at the beginning of the loop, but when k has a greater value than array's indices, pointing an index that array does not include...
Upvotes: 4
Views: 16825
Reputation: 46813
That's because at some point ${hitEnd[k]}
expands to nothing (it is undefined). I get the same error with ((l<=))
. You should write your for
loop as:
k=0
for ((l=${hitStart[0]};k<${#hitEnd[@]} && l<=${hitEnd[k]};l++)); do
so as to always have an index k
that corresponds to a defined field in the array ${hitEnd[@]}
.
Also, instead of
k=$((k+1))
you can just write
((++k))
Done!
Your script revised using better modern bash practice:
#!/bin/bash
k=0
#this loop is just for being sure array is loaded
while ((k<=${#hitEnd[@]})); do
echo "hitEnd is: ${hitEnd[k]} and hitStart is: ${hitStart[k]}"
# here outputs the values correct
((++k))
done
k=0
for ((l=hitStart[0];k<${#hitEnd[@]} && l<=hitEnd[k];++l)); do
((++array[l]))
((++k))
done
Now, I'm not too sure the for
loop does exactly what you want it to... Don't you mean this instead?
#!/bin/bash
# define arrays hitStart[@] and hitEnd[@]...
# define array array[@]
#this loop is just for being sure array is loaded
for ((k=0;k<${#hitEnd[@]};++k)); do
echo "hitEnd is: ${hitEnd[k]} and hitStart is: ${hitStart[k]}"
# here outputs the values correct
((++k))
done
for ((k=0;k<${#hitEnd[@]};++k)); do
for ((l=hitStart[k];l<=hitEnd[k];++l)); do
((++array[l]))
done
done
Upvotes: 4
Reputation: 47269
A bit bandaid-y, but you rewrite your for-loop into a while loop:
l="${hitStart[k]}"
while [[ "$l" -le "${hitEnd[k]}" ]]; do
let array[l]++
k=$((k+1))
l=$((l+1))
done
Upvotes: 1