I have a text file with a few basic words:
-banana
-mango
-sleep
When I run my script:
#!/bin/sh
WORD_FILE="testwoord.txt"
WORDS_ARRAY=cat $WORD_FILE
The output is like:
/home/username/bin/testword.txt: 1 /home/username/bin/restword.txt: banana: not found
/home/username/bin/testword.txt: 1 /home/username/bin/restword.txt: mango: not found
/home/username/bin/testword.txt: 1 /home/username/bin/restword.txt: sleep: not found
Why is it doing this? What I actually want is a script that reads words from a .txt file and puts it in an array.
To explain why this doesn't work:
WORDS_ARRAY=cat $WORD_FILE
runs the command generated by expanding, string-splitting, and glob-expanding $WORD_FILE
with the variable WORDS_ARRAY
exported in the environment with the value cat
.
Instead, consider:
#!/bin/bash
# ^^ -- important that this is bash, not sh: POSIX sh doesn't have arrays!
WORD_FILE=testword.txt
readarray -t WORDS_ARRAY <"$WORD_FILE"
printf 'Read a word: %q\n' "${WORDS_ARRAY[@]}"
...which will create an actual array, not a string variable containing whitespace (as WORDS_ARRAY=$(cat $WORD_FILE)
would).
By the way, using all-upper-case variable names is bad form here. To quote the POSIX spec:
Environment variable names used by the utilities in the Shell and Utilities volume of POSIX.1-2008 consist solely of uppercase letters, digits, and the ( '_' ) from the characters defined in Portable Character Set and do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names. Uppercase and lowercase letters shall retain their unique identities and shall not be folded together. The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.
To complement Charles Duffy's helpful answer:
Note that the variable names were changed to lowercase, as per Charles' recommendation.
Here a bash 3.x (and above) version of the command for reading lines into a bash array (readarray
requires bash 4.x):
IFS=$'\n' read -d '' -ra words_array < "$word_file"
If you want to store individual words (across lines), use:
read -d '' -ra words_array < "$word_file"
To print the resulting array:
for ((i=0; i<"${#words_array[@]}"; i++)); do echo "word #$i: "${words_array[i]}""; done