简体   繁体   English

我如何遍历数字数组并使用数组值更新 bash 中的数组

[英]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

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.我希望它从数组值 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.我想在这种情况下你需要两个嵌套循环。

  • The outer loop is to scan the array once using count .外循环是使用count扫描数组一次。
  • The inner loop is to identify the element that have value equal to count (0, then 1, then 2).内部循环是识别值等于count (0,然后 1,然后 2)的元素。
  • The 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM