12

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131

5 Answers5

17

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kojiro
  • 74,557
  • 19
  • 143
  • 201
9

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jordanm
  • 33,009
  • 7
  • 61
  • 76
2

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
Zioalex
  • 3,441
  • 2
  • 33
  • 30
0

Instead of this:

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

You can just do this:

Unix_Array=( `cat "hello.txt" `)
Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • Without reassigning `IFS`, this will create multiple elements for any line with a space in it. – kojiro Jun 18 '12 at 17:41
0

It’s a solution:

count=0
Unix_Array=($(cat hello.txt))
array_size=$(cat hello.txt | wc -l)
for ((count=0; count < array_size; count++))
do
    echo ${Unix_Array[$count]}
done
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arthur Alves
  • 458
  • 1
  • 5
  • 13
  • 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`. – kojiro Jun 19 '12 at 12:14