Reputation: 21
I am trying to increase the values of an array of integers using a variable, but it doesn't seem to be accessing the array values properly. It is to start from 0 in an ascending order, while incrementing the current array value at each iteration. I tried this:
array=(2 0 1)
tag=(H H H)
count=0
for i in ${array[@]}
do
if [[ "$array[$i]"="$count" ]]
then
array[$i]=$((${array[$i]}+1))
tag[$i]="C"
fi
count=$(($count + 1))
done
Instead it kept updating from 2, then 1, before 0. I want it to start from 0, since that is the index that is equal to count. This was the output.
0 H H C
2 0 2
1 C H C
3 0 2
2 C C C
3 1 2
Upvotes: 0
Views: 1575
Reputation: 1060
I guess that you need two nesting loops in this case.
count
.count
(0, then 1, then 2).tag
array is to avoid increasing the same element twice.OK, putting all that in code:
#!/bin/bash
array=(2 0 1)
tag=(H H H)
n=${#array[*]} ## array size
echo "${array[@]@A}; ${tag[@]@A};" ## for testing
for (( count=0; count<n; ++count )); do
for (( i=0; i<n; ++i )); do
if [[ ${array[$i]} -eq $count && ${tag[$i]} = "H" ]]; then
(( array[i]++ ))
tag[$i]="C" ## C=changed
break ## break inner loop
fi
done
echo "${array[@]@A}; ${tag[@]@A};" ## for testing
done
Results:
declare -a array=([0]="2" [1]="0" [2]="1"); declare -a tag=([0]="H" [1]="H" [2]="H");
declare -a array=([0]="2" [1]="1" [2]="1"); declare -a tag=([0]="H" [1]="C" [2]="H");
declare -a array=([0]="2" [1]="1" [2]="2"); declare -a tag=([0]="H" [1]="C" [2]="C");
declare -a array=([0]="3" [1]="1" [2]="2"); declare -a tag=([0]="C" [1]="C" [2]="C");
(sorry for my broken English)
Upvotes: 0
Reputation: 442
FYI: Bash indexing starts from 0 (so to change the 2-nd element you should consider index No. 1)
Note: Here the 0
in array
is somehow equal to 3
- last element! (so, using 3
would be more user-friendly).
Assuming the $array
values define the numbering element in $tag
to be changed (ex. 2 for 2nd, 3 for 3rd, and so on) accordingly, the following script will do the job.
script.sh
#!/bin/bash
#array=(2 0 1)
# Advantage of the logic of this script is that you may have more elements
# in $tag array but are able to change only a few of them that is mentioned in $array.
array=(2 3 1) # Change 2nd, 3rd, 1st elements accordingly.
tag=(H H H)
for i in `seq 1 ${#array[@]}` ;do
(( i-- ))
ii="${array[i]}"
(( ii-- ))
tag[$ii]="C"
echo -e "$i:\t${tag[@]}"
done
Output of the script.sh:
0: H C H
1: H C C
2: C C C
Just seen your comment, will try to update my script.
I want it to start from the array value 0, which is is the middle. So it should look like this, H C H > H C C > C C C
Script Updated, please check again!
Upvotes: 0
Reputation: 2778
In the loop iteration you are using array values instead of array indices, which is the core of the problem. So the TL;DR is: "${!array[@]}"
.
array=(2 0 1)
tag=(H H H)
echo "${array[@]@A}; ${tag[@]@A};"
for index in "${!array[@]}"; do
((++array[index]))
tag[index]=C
echo "${array[@]@A}; ${tag[@]@A};"
done
Output:
declare -a array=([0]="2" [1]="0" [2]="1"); declare -a tag=([0]="H" [1]="H" [2]="H");
declare -a array=([0]="3" [1]="0" [2]="1"); declare -a tag=([0]="C" [1]="H" [2]="H");
declare -a array=([0]="3" [1]="1" [2]="1"); declare -a tag=([0]="C" [1]="C" [2]="H");
declare -a array=([0]="3" [1]="1" [2]="2"); declare -a tag=([0]="C" [1]="C" [2]="C");
Upvotes: 3
Reputation: 155
One problem is that the values you are retrieving with the for
loop are integers that are being used as indexes to update the values of the array. A second problem is that your conditional statement is actually an assignment, so its exit code is always 0 (true), so $count, though incrementing, affects nothing.
First time through, $i==2, the third element of array
is incremented (array[2]==2), the third element of the tag
array is set to changed
The second time through, $i==0, the first element of array
is incremented (array[0]==3), the first element of tag
array is set to changed.
The third time through, $i==1 (see comment below), the second element of array
is incremented (array[1]==1), and the second element of the tag
array is set to changed.
Promised comment: In the third iteration, other languages would have $i==2 because array[2] had been incremented in the first loop. Bash is apparently iterating over the original values of the array, despite subsequent changes.
I think what you want to do is:
declare -a array=(2 0 1)
declare -a tag=("here" "here" "here")
declare -i count=0
declare -i i
echo "$count: ${array[*]}"
echo " ${tag[*]}"
for (( i=0; i<${#array[*]}; ++i )); do
(( array[i]++ )) # no need for '$' within (( ))
tag[$i]="changed"
(( count++ ))
echo "$count: ${array[*]}"
echo " ${tag[*]}"
done
I didn't include your conditional because I can't figure out what you're trying to do with it.
I added the echo
statements to create output similar to the output you claimed in your example.
Upvotes: 0