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
CodePudding user response:
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.
CodePudding user response:
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");
CodePudding user response:
FYI: Bash indexing starts from 0 (so to change the 2-nd element you should consider index No. 1) script.sh
#!/bin/bash
array=(2 0 1)
tag=(H H H)
for i in `seq 1 ${#array[@]}` ;do
(( i-- ))
ii="${array[i]}"
(( ii-- ))
tag[$ii]="C"
#(( array[i] ))
echo -e "$i:\t${tag[@]} \n\t${array[@]}"
done
Output of the script.sh:
0: H C H
2 0 1
1: H C C
2 0 1
2: C C C
2 0 1
Update:
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!