Search code examples
arraysbash

Iterate over and replace element in array


I am trying to replace the word "Apples" with "Cantaloupe" in my 'copy' array. What I am doing now is not throwing errors, but no change occurs in the copy array.

#!/bin/bash

fruits=("Oranges" "Apples" "Bananas" "Grapes")
echo "Original list:"
echo "${fruits[@]}"

copy=("${fruits[@]}")

for i in ${copy[@]}
do
        if [[ copy[$i] == "Apples" ]]; then
                copy[$i]="Cantaloupe"
        fi
done

echo "Copied list:"
echo "${copy[@]}"

My output:

Original list:
Oranges Apples Bananas Grapes
Copied list:
Oranges Apples Bananas Grapes

Solution

  • In your original approach you are looping over the keys in the array using which you would not be able to get the index of that element to replace.

    You need to change to modify the logic to loop over indices of the array as

    for i in "${!copy[@]}"; do
        if [[ ${copy[$i]} == "Apples" ]]; then
            copy[$i]="Canteloupe"
        fi
    done
    

    should solve your problem.

    The construct for i in "${!copy[@]}"; do is for looping with indices of the array starting from 0 to size of the array which lets you to replace the element in the index where you find the required string.


    Expanding the answer to point out the difference when using either of array iteration ways.

    Looping over indices

    for i in "${!copy[@]}"; do 
      printf "%s\t%s\n" "$i" "${copy[$i]}"
    done
    

    prints

    0       Oranges
    1       Apples
    2       Bananas
    3       Grapes
    

    and over keys

    for i in "${copy[@]}"; do 
      printf "%s\n" "$i"
    done
    

    produces,

    Oranges
    Apples
    Bananas
    Grapes