How can I assign a value to an array in Bash?

33,788

Solution 1

There are a few syntax errors here, but the clear problem is that the assignments are happening, but you're in an implied subshell. By using a pipe, you've created a subshell for the entire while statement. When the while statement is done, the subshell exits and your Unix_Array ceases to exist.

In this case, the simplest fix is not to use a pipe:

counter=0

while read line; do
  Unix_Array[$counter]=$line;
  let counter=counter+1;
  echo $counter;
done < hello.txt

echo ${Unix_Array[0]}
echo ${Unix_Array[1]}
echo ${Unix_Array[2]}

By the way, you don't really need the counter. An easier way to write this might be:

$ oIFS="$IFS" # Save the old input field separator
$ IFS=$'\n'   # Set the IFS to a newline
$ some_array=($(<hello.txt)) # Splitting on newlines, assign the entire file to an array
$ echo "${some_array[2]}" # Get the third element of the array
c
$ echo "${#some_array[@]}" # Get the length of the array
4

Solution 2

If you are using Bash v4 or higher, you can use mapfile to accomplish this:

mapfile -t Unix_Array < hello.txt

Otherwise, this should work:

while read -r line; do
   Unix_Array+=("$line")
done < hello.txt

Solution 3

The best way I found is:

declare -a JUPYTER_VENV
JUPYTER_VENV+=( "test1" "test2" "test3" )

And then consume it with:

for jupenv in "${JUPYTER_ENV[@]}"
do
  echo "$jupenv"
done
Share:
33,788
Admin
Author by

Admin

Updated on October 26, 2021

Comments

  • Admin
    Admin over 2 years

    I am trying to read a list of values from a text file, hello.txt, and store them in an array.

    counter=0
    
    cat hello.txt | while read line; do
     ${Unix_Array[${counter}]}=$line;
     let counter=counter+1;
        echo $counter;
    done
    
    echo ${Unix_Array[0]}
    echo ${Unix_Array[1]}
    echo ${Unix_Array[2]}
    

    I am not able to assign values to the array Unix_Array[]... The echo statement does not print the contents of the array.

  • user2584401
    user2584401 almost 12 years
    The implied subshell didn't even occur to me.
  • kojiro
    kojiro almost 12 years
    Without reassigning IFS, this will create multiple elements for any line with a space in it.
  • kojiro
    kojiro almost 12 years
    +1 for calling out mapfile. I always forget about the new shell features.
  • kojiro
    kojiro almost 12 years
    This suffers from the same problem as Jon Lin's solution, namely, that you have to set IFS to a newline or you'll split on any whitespace in hello.txt.
  • ghoti
    ghoti over 9 years
    +1. Also, note that putting IFS=$'\n' declare some_array=($(<hello.txt)) all on one line means that you don't have to save IFS in oIFS. When used this way, the IFS variable is set only for the command line it precedes. Note that declare is the command here; without it, you only have a couple of variable assignments.
  • tripleee
    tripleee over 2 years
    I think you mean declare -a; the uppercase version declares an assoclative array (Bash 4+).