[英]how do i loop through an array of numbers and update the array in bash using the array values
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.
它是从0开始按升序排列,同时在每次迭代时递增当前数组值。 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.相反,它不断从 2、1、0 之前更新。我希望它从 0 开始,因为这是等于计数的索引。 This was the output.
这是 output。
0 H H C
2 0 2
1 C H C
3 0 2
2 C C C
3 1 2
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[@]}"
.所以 TL;DR 是:
"${!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: 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");
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.一个问题是您使用
for
循环检索的值是用作索引以更新数组值的整数。 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.第二个问题是你的条件语句实际上是一个赋值,所以它的退出代码总是 0(真),所以 $count 虽然递增,但没有任何影响。
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第一次通过,$i==2,
array
的第三个元素自增(array[2]==2), tag
数组的第三个元素设置为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 .第二次通过,$i==0,
array
的第一个元素递增(array[0]==3), tag
数组的第一个元素被设置为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 .第三次,$i==1(见下面的注释),
array
的第二个元素递增(array[1]==1), tag
数组的第二个元素设置为changed 。
Promised comment: In the third iteration, other languages would have $i==2 because array[2] had been incremented in the first loop.承诺的评论:在第三次迭代中,其他语言将有 $i==2 因为 array[2] 在第一个循环中增加了。 Bash is apparently iterating over the original values of the array, despite subsequent changes.
Bash 显然是在迭代数组的原始值,尽管随后发生了变化。
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.我添加了
echo
语句来创建 output,类似于您在示例中声明的 output。
FYI: Bash indexing starts from 0 (so to change the 2-nd element you should consider index No. 1)仅供参考: Bash 索引从 0 开始(因此要更改第二个元素,您应该考虑索引号 1)
Note: Here the 0
in array
is somehow equal to 3
- last element, (so, using 3
would be more user-friendly).注意:此处
array
中的0
不知何故等于3
- 最后一个元素(因此,使用3
会更加用户友好)。
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.假设
$array
值定义了要更改的$tag
中的编号元素(例如,2 代表第 2 个,3 代表第 3 个,依此类推),以下脚本将完成这项工作。
script.sh脚本.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: script.sh 的 Output:
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.
我希望它从数组值 0 开始,也就是中间的值。 So it should look like this, H C H > H C C > C C C
所以它应该是这样的, H C H > H C C > C C C
Script Updated, please check again!脚本已更新,请再次检查!
I guess that you need two nesting loops in this case.我想在这种情况下你需要两个嵌套循环。
count
.count
扫描数组一次。count
(0, then 1, then 2).count
(0,然后 1,然后 2)的元素。tag
array is to avoid increasing the same element twice. tag
数组是为了避免将同一个元素增加两次。 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) (抱歉我的英语不好)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.